Before the introduction of exceptions in SWI-Prolog a runtime error was handled by printing an error message, after which the predicate failed. If the prolog_flag (see current_prolog_flag2) debug_on_error was in effect (default), the tracer was switched on. The combination of the error message and trace information is generally sufficient to locate the error.
With exception handling, things are different. A programmer may wish to trap an exception using catch3 to avoid it reaching the user. If the exception is not handled by user-code, the interactive toplevel will trap it to prevent termination.
If we do not take special precautions, the context information associated with an unexpected exception (i.e. a programming error) is lost. Therefore, if an exception is raised, which is not caught using catch3 and the toplevel is running, the error will be printed, and the system will enter trace mode.
If the system is in an non-interactive callback from foreign code and there is no catch3 active in the current context, it cannot determine whether or not the exception will be caught by the external routine calling Prolog. It will then base its behaviour on the prolog_flag debug_on_error:
While looking for the context in which an exception takes place, it is adviced to switch on debug mode using the predicate debug0.