pack_errors.pl -- Contextual error handling for packs

This is a stoics.infrastructure pack for

  1. mid-level management handling of pack errors,
  2. provide a simple, uniform way for informing users where the errors come from, and
  3. provide useful pre-canned errors.

As of 0.3 the library also provides type errors on top of must_be/2

The main aim is to create contextual version of messages that can be used from different packs. In addition the library has evolved to provide some error related predicates.

Wrapper errors

Providing the context:

pack_error(Pack, Pred, Vrb, Message)
spew Message in the context of Pack and Predicate. Vrb controls printing of context info. when Vrb is false there is no message about the pack the error originated from
pack_error(Pack, Pred, Message)
as above with Vrb = true
pack_error(Pack, Message)
as above without Predicate context

Prepacked errors

Argument errors (printing of Arg itself can be surpressed with prolog_flag(pack_errors_arg,false)- useful for long data). Poss is a list of positions and Args a list of arguments.

Other errors

Examples

?- throw( pack_error(os,arg_ground(3,name(_))) ).
ERROR: pack(os): Ground argument expected at position: 3 (found: name(_2064))
?- set_prolog_flag(pack_errors_arg,false).
?- throw( pack_error(os,arg_ground(3,name(_))) ).
ERROR: pack(os): Ground argument expected at position: 3
?- set_prolog_flag(pack_errors_arg,true).
?- throw( pack_error(os,os_pred/3,arg_ground(3,name(_))) ).
ERROR: os:os_pred/3: Ground argument expected at position: 3 (found: name(_2088))
?- throw( pack_error(os,os_pred/3,arg_enumerate(3,[a,b,c],d)) ).
ERROR: os:os_pred/3: Term at position: 3, is not one of: [a,b,c], (found: d)

?- throw( pack_error(mlu,lengths_mismatch(learners,predictions,3,4)) ).
ERROR: pack(mlu): Lists for learners and predictions have mismatching lengths: 3 and 4 respectively
?- throw( pack_error(mlu,k_fold_learn/3,lengths_mismatch(learners,predictions,3,4)) ).
ERROR: mlu:k_fold_learn/3: Lists for learners and predictions have mismatching lengths: 3 and 4 respectively
?- throw( pack_error(os,os_term/2,cast(abc('file.csv'),atom)) ).
ERROR: os:os_term/2: Cannot cast: abc(file.csv), to type: atom

Defining new pack errors

example file:

:- multifile( pack_errors:message/3 ).

pack_errors:message( fold_data_insufficient(Dlen,N) ) -->
    ['Insufficient length of data (~d) as ~d folds are required'-[Dlen,N]].
pack_errors:message( fold_data_residual(Dlen) ) -->
    ['Residual data of length: ~d while splitting folds'-[Dlen]].

Once the above has been loaded, try with

?- throw( fold_data_insufficient(10,20) ).
ERROR: Insufficient length of data (10) as 20 folds are required
?- throw( pack_error(mlu,fold_data_insufficient(10,20) ) ).
ERROR: pack(mlu): Insufficient length of data (10) as 20 folds are required
?- throw( pack_error(mlu,k_fold_learn/4,fold_data_insufficient(10,20) ) ).
ERROR: mlu:k_fold_learn/4: Insufficient length of data (10) as 20 folds are required

Pack info

The library listens to debug(pack_errors).

author
- nicos angelopoulos
version
- 0.1 2016/01/30
- 0.2 2016/02/24
- 0.3 2017/03/06
See also
- http://stoics.org.uk/~nicos/sware/pack_errors
- lib predicates:
- caught/3 args, +Goal, +Call, +Opts
- ground/2, ground_binary/2 args: +Term, -Groundness
- throw/2 args: +Ball, +Opts
- type/2, type/3 args: +Type, +Term [, +Opts]
- pack_errors/0, pack_errors_version/2 args: +Version, +Date
To be done
- equal length list checking
caught(+Goal, +Error, +Opts)
Catches all errors and failure of Goal. The idea is that all non-successful executions are handled identical by the call. If Goal errors, the primary thrown ball is caught and discarded. If Goal errors or fails, behaviour depends on option value Report (see Opts below).

Opts

?- caught( fail, my_exception(on_data), true ).
ERROR: Unhandled exception: my_exception(on_data)

?- caught( fail, my_exception(on_data), [report(ignore)] ).
true

?- caught( fail, my_exception(on_data), [report(fail)] ).
false

?- caught( xyz, my_except(Ball), [ball(Ball)] ).
ERROR: Unhandled exception: my_except(error(existence_error(procedure,pack_errors:xyz/0),context(system:catch/3,_11198)))
See also
- throw/2
ground(+Term, -Groundness)
ground_binary(+Term, -Groundness)
Instantiates groundness of Term to Type. In ground_binary/2 Groundness partial and false are collapsed to false.

Groundness

true
Term is ground
false
Term is variable
partial
Term is partially instantiated

== ?- ground( abc, Abc ), ground( de(F), Def ), ground( GHI, Ghi ). Abc = true, Def = partial, Ghi = false.

?- ground_binary( abc, Abc ), ground_binary( de(F), Def ), ground_binary( GHI, Ghi ). Abc = true, Def = Ghi, Ghi = false.

throw(+Error, +Opts)
An optionised version of throw/1. Error is not thrown if OnThrow==fail (see Opts below) and the call to throw/2 itself fails. When OnThrow==succeed Error is not thrown and the call itself succeeds. For all other values the default behaviour is that of OnThrow==error where is to thrown Error is assumed.
Opts on_throw(OnThrow=error) one of [succeed,fail,error].
?- throw( my_error(x), true ).
ERROR: Unhandled exception: my_error(x)

?- throw( my_error(x), on_throw(succeed) ).
true.

?- throw( my_error(x), on_throw(fail) ).
false.

?- throw( my_error(x), on_throw(error) ).
ERROR: Unhandled exception: my_error(x)

?- throw( my_error(x), on_throw(whatelse) ).
ERROR: Unhandled exception: my_error(x)
version
- 0.2 2017/3/6
type(+Type, @Term)
type(+Type, @Term, +Opts)
type/2 is a superset of must_be, in that it adds Type = call(Callable), which will succeed iff call( Callable, Term ) succeeds. It also enhances must_be/2 by adding options . In the case of a call-wrapped type, the call to type/3 will succeed iff call(Callable,Term) succeeds.

Opts (unlisted is ok)

?- type( boolean, maybe ).
ERROR: Object of type: boolean, expected but found term: maybe
?- type( boolean, maybe, error(false) ).
false.
?- type( boolean, maybe, pack(sure) ).
ERROR: pack(sure): Object of type: boolean, expected but found term: maybe
?- type( boolean, maybe, [pack(sure),pred(lost/2)] ).
ERROR: sure:lost/2: Object of type: boolean, expected but found term: maybe
?- type( boolean, maybe, [pack(sure),pred(lost/2@3)] ).
ERROR: Syntax error: Operator expected
ERROR: type( boolean, maybe, [pack(sure),pred(lost/
ERROR: ** here **
ERROR: 2@3)] ) .
?- type( boolean, maybe, [pack(sure),pred(lost/2+3)] ).
ERROR: sure:lost/2+3: Object of type: boolean, expected but found term: maybe
?- type( boolean, maybe, [pack(sure),pred(1+lost/2)] ).
ERROR: sure:1+lost/2: Object of type: boolean, expected but found term: maybe
?- type( boolean, maybe, [pack(sure),pred(lost(arg1)/2)] ).
ERROR: sure:lost(arg1)/2: Object of type: boolean, expected but found term: maybe
pack_errors
This is a documentation predicate, providing an anchor for documentation pointers.
pack_errors_version(-Version, -Date)
Current version and release date for the library.

Currently: pack_errors_version( 0:3:0, date(2017,3,6) ).