This simulates an occurrence of the error EventId inside a call to Culprit in Module. The valid error numbers are those returned by current_error/1. Event names can be any atom as long as an event handler has been defined for them.
If EventId is a structure with functor default/1, the structure argument is taken as the error number and the default handler is executed, even if the error handler has been redefined using set_event_handler/2. This is useful for writing user error handlers.
If the event handler succeeds, possibly binding some variables inside Culprit, then error/3 succeeds as well. If the handler fails or calls throw/1, then so does error/3.
Not that when the error handler ignores the module (ie. has arity less than three), then error/2 and error/3 are equivalent.
Success: ?- error(68, length(X, Y), lists). calling an undefined procedure eclipse:length(X, Y) in module lists % writing an alternative error handler for undefined predicates: ?- arg(1,2). % we want to change this calling an undefined procedure arg(1, 2) in module eclipse ?- [user]. % compile the new handler undef_handler(_, Goal, _Context, Module) :- functor(Goal, Name, BadArity), ( current_predicate(Name/Arity)@Module ; current_built_in(Name/Arity)@Module ), !, printf("%w does not exist, but there is %w\n", [Name/BadArity, Name/Arity]), fail. undef_handler(Err, Goal, Context, Module) :- error(default(Err), Goal, Context, Module). user compiled 592 bytes in 0.02 seconds yes. ?- set_event_handler(68, undef_handler/4). yes. ?- arg(1,2). % check if it works arg / 2 does not exist, but there is arg / 3 no. Error: error(N,dummy(1),eclipse). (Error 4). error(5.0,dummy(1),eclipse). (Error 5). error(-2,dummy(1),eclipse). (Error 6). error(95,dummy(1),eclipse). (Error 6).