This simulates an occurrence of the error EventId inside a call to Culprit. 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's 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/2 succeeds as well. If the handler fails or calls throw/1, then so does error/2.
Success: % Writing a predicate with type checking ?- [user]. is_positive(N) :- number(N), !, N >= 0. is_positive(N) :- error(5, is_positive(N)). user compiled 244 bytes in 0.02 seconds yes. ?- is_positive(a). type error in is_positive(a) % changing the behaviour of a built-in by redefining a handler ?- //(1,0,X). % change this behaviour arithmetic exception in //(1, 0, X) ?- [user]. % define the new handler my_handler(_, //(_,_,Result)) :- !, Result = infinity. my_handler(Err, Goal) :- error(default(Err), Goal). user compiled 212 bytes in 0.00 seconds yes. ?- set_event_handler(20, my_handler/2). yes. ?- //(1,0,X). % check if it works X = infinity yes. ?- sqrt(-1,X). % other culprits: as before arithmetic exception in sqrt(-1, _g36) Error: error(N,dummy(1)). (Error 4). error(5.0,dummy(1)). (Error 5). error(-2,dummy(1)). (Error 6).