I’m using: SWI-Prolog version 8.0.2
Occasionally I get fatal errors in my code running under PEngines, usually with the predicate atomics-to_string
due to an Arguments are not sufficiently instantiated error.
PEngines catches the error without crashing, that’s good. But I am wondering if there is a way to do the equivalent of a try/catch around functions like atomics_to_string
that can cause a fatal error like that, so I can handle the error myself, or at least add some context to help with debugging?
Also, is there a way to get PEngines to deliver a full stack trace instead of just an error message?:
Object received: {
"code": "instantiation_error",
"data": "atomics_to_string/2: Arguments are not sufficiently instantiated",
"event": "error",
"id": "21b36912-e160-4898-9a40-d83b3d10b410",
"pengine": {
"options": {
"server": "http://localhost:3030/pengine",
"application": "tsll",
"destroy": false,
"src_text": "(removed)",
"format": "json"
},
"id": "21b36912-e160-4898-9a40-d83b3d10b410",
"request": {}
}
}
In the meantime I am using code like that below to help my debugging efforts, but I am hoping there are things intrinsic to SWi-Prolog to replace or augment what the code below does:
% ----->>>>> is_any_list_element_var
% This predicate succeeds if any element in the list is not ground.
% Did not find any var() list elements. Fail the function.
is_any_list_element_var_1([]) :- !, fail.
is_any_list_element_var_1([H | _]) :-
var(H),
!.
is_any_list_element_var_1([_ | T]) :-
!,
is_any_list_element_var_1(T).
is_any_list_element_var(List) :-
is_list(List),
!,
is_any_list_element_var_1(List).
is_any_list_element_var(_) :-
x_write('(is_any_list_element_var) ERROR: The list parameter is not a list.'),
!.
% ----->>>>> wrap_atomics_to_string
% Wrap the atomics_to_string predicate in an attempt to achieve better debugging
% capabilities when calling that predicate.
% Validate the Caller parameter.
wrap_atomics_to_string(Caller, _, _) :-
var(Caller),
x_write('(wrap_atomics_to_string) ERROR: The caller parameter should be ground.'),
!.
% Validate the List parameter as being a list.
wrap_atomics_to_string(Caller, List, _) :-
is_list(List),
x_write('(wrap_atomics_to_string) ERROR: The list parameter should be ground. Called by: '),
x_write(Caller),
!.
% Check for an empty list.
wrap_atomics_to_string(Caller, List, _) :-
is_list(List),
length(List, 0),
x_write('(wrap_atomics_to_string) ERROR: The list parameter is empty. Called by: '),
x_write(Caller),
!.
% Make sure every element in the list to be passed to atomics_to_string is ground.
wrap_atomics_to_string(Caller, List, _) :-
is_any_list_element_var(List),
x_write('(wrap_atomics_to_string) ERROR: The list parameter contains one or more elements that are not ground. Called by: '),
x_write(Caller),
!.
% Should be OK to call atomics_to_string now.
wrap_atomics_to_string(Caller, List, StrOut) :-
x_write('(wrap_atomics_to_string) Calling atomics_to_string from: '),
x_write(Caller),
x_write(', with list content: '),
x_write(List),
atomics_to_string(List, StrOut),
x_write('(wrap_atomics_to_string) Successful call.'),
!.