Skip to content

Commit 2402a21

Browse files
jjtoltonclaude
andcommitted
Add --halt-on-error flag for safer scripting
This flag causes Scryer Prolog to terminate with exit code 1 when encountering errors, instead of dropping into the REPL. This makes it much safer to use Scryer in scripting contexts, CI/CD pipelines, and automated testing. The flag affects error handling in: - Goal execution (via -g flag) - File loading/consultation - Initialization failures - Exception handling in the REPL Usage: scryer-prolog --halt-on-error my_file.pl scryer-prolog --halt-on-error -g "my_goal" Resolves: #3146 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: J.J.'s Robot <jjtolton@gmail.com>
1 parent e4d9692 commit 2402a21

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/machine/args.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ use std::env;
44
#[derive(Debug)]
55
pub struct MachineArgs {
66
pub add_history: bool,
7+
pub halt_on_error: bool,
78
}
89

910
impl MachineArgs {
1011
pub fn new() -> Self {
1112
let args: BTreeSet<String> = env::args().collect();
1213
Self {
1314
add_history: !args.contains("--no-add-history"),
15+
halt_on_error: args.contains("--halt-on-error"),
1416
}
1517
}
1618
}

src/toplevel.pl

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
; member(Arg0, ["-g", "--goal"]) -> gather_goal(g, Args, Goals0)
8080
; member(Arg0, ["-f"]) -> disable_init_file
8181
; member(Arg0, ["--no-add-history"]) -> ignore_machine_arg
82+
; member(Arg0, ["--halt-on-error"]) -> ignore_machine_arg
8283
),
8384
!,
8485
delegate_task(Args, Goals0)
@@ -100,6 +101,8 @@
100101
write('Fast startup. Do not load initialization file (~/.scryerrc)'), nl,
101102
write(' --no-add-history '),
102103
write('Prevent adding input to history file (~/.scryer_history)'), nl,
104+
write(' --halt-on-error '),
105+
write('Terminate with exit code 1 on errors instead of entering REPL'), nl,
103106
% write(' '),
104107
halt.
105108

@@ -154,19 +157,31 @@
154157
Exception,
155158
( write_term(Goal, [variable_names(VNs),double_quotes(DQ)]),
156159
write(' causes: '),
157-
write_term(Exception, [double_quotes(DQ)]), nl % halt?
160+
write_term(Exception, [double_quotes(DQ)]), nl,
161+
( halt_on_error_enabled ->
162+
halt(1)
163+
; true
164+
)
158165
)
159166
) -> true
160167
; write('% Warning: initialization failed for: '),
161-
write_term(Goal, [variable_names(VNs),double_quotes(DQ)]), nl
168+
write_term(Goal, [variable_names(VNs),double_quotes(DQ)]), nl,
169+
( halt_on_error_enabled ->
170+
halt(1)
171+
; true
172+
)
162173
),
163174
run_goals(Goals).
164175
run_goals([c(Mod)|Goals]) :- !,
165-
( catch(consult(Mod), E, print_exception(E)) ->
176+
( catch(consult(Mod), E, (print_exception(E), (halt_on_error_enabled -> halt(1) ; true))) ->
166177
true
167178
; write('% Warning: initialization failed for: '),
168179
double_quotes_option(DQ),
169-
write_term(consult(Mod), [double_quotes(DQ)]), nl
180+
write_term(consult(Mod), [double_quotes(DQ)]), nl,
181+
( halt_on_error_enabled ->
182+
halt(1)
183+
; true
184+
)
170185
),
171186
run_goals(Goals).
172187
run_goals([Goal|_]) :-
@@ -542,6 +557,10 @@
542557
gather_equations(Pairs, OrigVarList, Goals0)
543558
).
544559

560+
halt_on_error_enabled :-
561+
raw_argv(Args),
562+
member("--halt-on-error", Args).
563+
545564
print_exception(E) :-
546565
( E == error('$interrupt_thrown', repl) -> nl % print the
547566
% exception on a
@@ -550,7 +569,11 @@
550569
; true
551570
),
552571
loader:write_error(E),
553-
nl.
572+
nl,
573+
( halt_on_error_enabled ->
574+
halt(1)
575+
; true
576+
).
554577

555578
print_exception_with_check(E) :-
556579
( E = error(_, _:_) -> true % if the error source contains a line

0 commit comments

Comments
 (0)