12.4.15 Prolog exceptions in foreign code
AllApplicationManualNameSummaryHelp

  • Documentation
    • Reference manual
      • Foreign Language Interface
        • The Foreign Include File
          • Prolog exceptions in foreign code
            • PL_raise_exception()
            • PL_throw()
            • PL_exception()
            • PL_clear_exception()
    • Packages
Availability:C-language interface function
int PL_raise_exception(term_t exception)
Generate an exception (as throw/1) and return FALSE. This function is rarely used directly. Instead, errors are typically raised using the functions in section 12.4.6 or the C api functions that end in _ex such as PL_get_atom_ex(). Below we give an example returning an exception from a foreign predicate the verbose way. Note that the exception is raised in a sequence of actions connected using &&. This ensures that a proper exception is raised should any of the calls used to build or raise the exception themselves raise an exception. In this simple case PL_new_term_ref() is guaranteed to succeed because the system guarantees at least 10 available term references before entering the foreign predicate. PL_unify_term() however may raise a resource exception for the global stack.
foreign_t
pl_hello(term_t to)
{ char *s;

  if ( PL_get_atom_chars(to, &s) )
  { Sprintf("Hello \"%s\"\n", s);

    return TRUE;
  } else
  { term_t except;

    return  ( (except=PL_new_term_ref()) &&
              PL_unify_term(except,
                            PL_FUNCTOR_CHARS, "type_error", 2,
                              PL_CHARS, "atom",
                              PL_TERM, to) &&
              PL_raise_exception(except) );
  }
}

For reference, the preferred implementation of the above is below. The CVT_EXCEPTION tells the system to generate an exception if the conversion fails. The other CVT_ flags define the admissible types and REP_MB requests the string to be provided in the current locale representation. This implies that Unicode text is printed correctly if the current environment can represent it. If not, a representation_error is raised.

foreign_t
pl_hello(term_t to)
{ char *s;

  if ( PL_get_chars(to, &s, CVT_ATOM|CVT_STRING|CVT_EXCEPTION|REP_MB) )
  { Sprintf("Hello \"%s\"\n", s);

    return TRUE;
  }

  return FALSE;
}