See also Prolog exceptions in foreign code.
Prolog exceptions are mapped to C++ exceptions using the class
PlException (a subclass of PlExceptionBase to 
represent the Prolog exception term. All type-conversion functions of 
the interface raise Prolog-compliant exceptions, providing decent 
error-handling support at no extra work for the programmer.
For some commonly used exceptions, convenience functions have been 
created to exploit both their constructors for easy creation of these 
exceptions. If you wish to trap these, you should use
PlException or PlExceptionBase and then look 
for the appropriate error name. For example, the following code catches
"type_error" and passes all other exceptions:
try
{ do_something(...);
} catch (const PlException& e)
{ PlTerm e_t = e.term();
  PlAtom ATOM_type_error("type_error");
  // e_t.name() == PlAtom("error") && e_t.arity() == 2
  if ( e_t[1].name() == ATOM_type_error) )
  { ... // expected type and culprit are \exam{e_t[1][1]} and \exam{e_t[1][2]}
  } else throw;
}
The convenience functions are PlTypeEror() and PlDomainError(),
PlDomainError(), PlInstantiationError(), PlExistenceError(),
PlUninstantiationError(), PlRepresentationError(),
PlPermissionError(), PlResourceError(), PlUnknownError(). 
There is also a PlGeneralError(inside) that creates error(inside,_) 
terms and is used by the other error convience functions.
To throw an exception, create an instance of PlException 
and use throw. This is intercepted by the PREDICATE macro 
and turned into a Prolog exception. See section 
1.17.2.
  char *data = "users";
  throw PlException(PlCompound("no_database", PlTerm(data)));
This subclass of PlExceptionBase is used to represent 
exceptions.
PlException, there are convenience functions that create 
and wrap a Prolog term, similar to the PL_domain_error(), etc. 
The hierarchy allows catch statements to easily handle 
combinations.
A PlException object contains a Prolog term, so its
what() method must be called either 
within a Prolog predicate or within the context of a PlEngine 
(and PlFrame; see section 
1.16). The term is copied so that it is available outside of the 
context of the frame that created it.
std::exception
*-- PlExceptionBase
    *-- PlException
    |   *.. PlDomainError()
    |   *.. PlExistenceError()
    |   *.. PlGeneralError()
    |   *.. PlInstantiationError()
    |   *.. PlPermissionError()
    |   *.. PlRepresentationError()
    |   *.. PlResourceError()
    |   *.. PlTypeError()
    |   *.. PlUninstantiationError()
    |   *.. PlUnknownError()
    *-- PlExceptionFailBase
    |   *-- PlExceptionFail
    |   *-- PlFail
    *-- PlEngineInitialisationFailed
    *-- PlOpenForeignFrameFailed
Note that everything under PlException can contain a 
Prolog term; if the what() method is 
called, it must be within the context of a Prolog frame. If you wish to 
pass the exception outside the frame, you can use the set_what_str() 
method to avoid evaluating the term after it has been freed by Prolog:
  try
  { PlCall("p(123)");
      ...
  } catch ( PlException &ex )
  { ex.set_what_str();
    throw; // rethrow the exception
  }
Currently defined methods are:
  ...;
  try
  { PlCall("consult(load)");
  } catch ( const PlException& ex )
  { cerr << ex.as_string() << endl;
  }
A type error expresses that a term does not satisfy the expected basic Prolog type.
A domain error expresses that a term satisfies the basic 
Prolog type expected, but is unacceptable to the restricted domain 
expected by some operation. For example, the standard Prolog open/3 
call expect an io_mode (read, write, append, ...). If an 
integer is provided, this is a type error, if an atom other 
than one of the defined io-modes is provided it is a domain error.