If Number is not an integer but 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_error_handler/2. This is useful for writing user error handlers.
If the error handler fails or calls exit_block/1, the execution continues in the appropriate way. If the error handler succeeds, possibly binding some variables, error/2 succeeds.
error/2 is defined by
error(N, G) :- error(N, G, _).
Success: % Writing a predicate with type checking [eclipse]: [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. [eclipse]: is_positive(a). type error in is_positive(a) % changing the behaviour of a built-in by redefining a handler [eclipse]: ln(0,X). % change this behaviour arithmetic exception in ln(0, _g36) [eclipse]: [user]. % define the new handler my_handler(_, ln(_, Result)) :- !, Result = infinity. my_handler(Err, Goal) :- error(default(Err), Goal). user compiled 212 bytes in 0.00 seconds yes. [eclipse]: set_error_handler(20, my_handler/2). yes. [eclipse]: ln(0,X). % check if it works X = infinity yes. [eclipse]: 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).