I’ve read and reread the documentation for the exception term for throw/1, and I’m still confused.
For one thing, in error(..., context(Location,Message)
, the backtrace doesn’t seem to fill in Location
:
?- listing(type_check:control_type_error).
control_type_error(Error, Goal, Context) :-
throw(error(Error, context(Goal, Context))).
?- type_check:control_type_error(failure, 1=2, qqsv).
ERROR: Unknown error term: failure (qqsv)
ERROR: In:
ERROR: [11] throw(error(failure,context(...,qqsv)))
ERROR: [9] toplevel_call(user:type_check: ...) at /usr/lib/swi-prolog/boot/toplevel.pl:1113
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
If I want to define a predicate that throws an exception on failure, is this the best way?
must_once(Goal) :-
( call(Goal)
-> true
; throw(error(must_once_failed, context(_,goal:Goal)))
).
Or is this better?
must_once_msg(Goal, Msg, MsgArgs) :-
( call(Goal)
-> true
; functor(Goal, Pred, Arity),
format(string(MsgStr), Msg, MsgArgs),
throw(error(must_once_failed(Goal),
context(Pred/Arity, MsgStr)))
).
Or something else?