Skip to content

Improve break-loop stack traces#6257

Open
fingolfin wants to merge 5 commits intomasterfrom
codex/improve-error-handling
Open

Improve break-loop stack traces#6257
fingolfin wants to merge 5 commits intomasterfrom
codex/improve-error-handling

Conversation

@fingolfin
Copy link
Member

@fingolfin fingolfin commented Mar 9, 2026

This reworks break-loop stack traces so the initial traceback and later Where() output are driven by the same visible traceback state.

The break loop now tracks both the real environment used for local variable lookup and the first visible traceback frame. That makes ordinary errors, kernel-thrown errors, and no-method-found errors behave more consistently: Where() now shows the same top visible frame that was shown on entry, while method-not-found still keeps its helper environment available for ShowArguments, ShowDetails, and ShowMethods.

This also adds CurrentEnv() for inspecting the currently selected break-loop environment and updates the break-loop docs and tests accordingly.

On top of that, visible stack frames are now rendered with numbered prefixes in the style *[1], [2], [3], where the * denotes the active frame. For me, that makes it much easier to use DownEnv/UpEnv correctly, and also increases readability of in longer traces. The manual examples and special REPL transcripts were refreshed to match the new output.

AI disclosure: prepared with help from Codex for implementation, tests, and documentation.

Resolves #4577

The diff contains many concrete examples where you can see how the stack traces changed in concrete examples. I'd be happy to add additional scenarios if I missed any!

fingolfin and others added 2 commits March 9, 2026 17:51
Track both the active break-loop environment and the first
visible traceback frame so automatic tracebacks and Where
agree, mark the active visible frame, and keep
method-not-found recovery helpers available.

Add CurrentEnv() for inspecting the selected environment and
refresh the REPL and manual expectations accordingly.

AI-assisted with Codex for implementation, tests, and
documentation.

Co-authored-by: Codex <codex@openai.com>
Render visible break-loop stack frames with Julia-style
numbered prefixes so the active frame is shown as *[n]
and the remaining frames as [n].

Adjust the statement printer interface, manual examples,
and regenerated special-test expectations to match the new
stack trace format.

AI-assisted with Codex for implementation, tests, and
documentation.

Co-authored-by: Codex <codex@openai.com>
@fingolfin fingolfin added kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements topic: error handling release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes labels Mar 9, 2026
@james-d-mitchell
Copy link
Contributor

On top of that, visible stack frames are now rendered with numbered prefixes in the style *[1], [2], [3], where the * denotes the active frame. For me, that makes it much easier to use DownEnv/UpEnv correctly, and also increases readability of in longer traces. The manual examples and special REPL transcripts were refreshed to match the new output.

This looks really nice in the manual entry you've added, I'll try to take a closer look first thing tomorrow.

test( n + 1 ); called from
test( n + 1 ); called from
<function>( <arguments> ) called from read-eval-loop
*[1] Error( "!\n" ); at *stdin*:3 called from
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note how this used to be missing in the stack trace

fingolfin and others added 2 commits March 9, 2026 19:12
Remove the unused printThisStatement plumbing from the
kernel-side ErrorInner helper now that every caller passed
1 and ErrorInner no longer reads that option.

AI-assisted with Codex for implementation and verification.

Co-authored-by: Codex <codex@openai.com>
ErrorInner(
rec(
context := GetCurrentLVars(),
tracebackContext := ParentLVars(GetCurrentLVars()),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The introduction of tracebackContext (as a replacement for printThisStatement) is key to fixing the inconsistencies (and not realizing this was probably the main reason I failed before)

@fingolfin
Copy link
Member Author

There are a bunch of manual examples involving stacktraces that are not yet updated. I'll do that.

But I also have a bunch of further ideas for improvements I have, but perhaps better to do them in follow-ups.

@ChrisJefferson
Copy link
Contributor

This is much better. There are numerous ways this could be improved but I think this is good for now, and well tested.

Copy link
Contributor

@james-d-mitchell james-d-mitchell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great, just played around for a while, I think we should merge!

One possible improvement for the future would be to make UpEnv and DownEnv call Where so the context is clear:

brk> DownEnv();
 [1] Error( "!\n" ); at *stdin*:3 called from
 [2] test( n + 1 ); at *stdin*:3 called from
*[3] test( n + 1 ); at *stdin*:3 called from
 [4] test( n + 1 ); at *stdin*:3 called from
<function "test">( <arguments> )
 called from read-eval loop at *errin*:5

@fingolfin
Copy link
Member Author

So it turns out that there are more break loop logs in the manual and some source code than I thought -- and they all are outdated, in fact they already are outdated on master, as none were updated when we made changes to the breakloop in past years.

I already have been working on a PR with further tweaks. Untangling that from the break loop log updates (which unfortunately I made after addition tweaks to the stack trace formatting) would be extra work -- so here is my proposal: we merge this now, as-is, if y'all agree.

Then I'll make another PR which updates those logs, and further tweaks the stacktrace printing. If people like it, we can merge it. If people hate it, I can still do the extra work of updating the logs again (I have to manually interact with that as the AI is confused by code it can't actually execute because e.g. it triggers a segfault intentionally)

BTW some of those logs were so ancient that they can't properly be reproduced. I also found some parts that were showing break loop for a bad reason: they used to show working code, which at some point became illegal, but instead of modifying it to show valid outputs, it was instead modified to show the error -- as a result the log did not fix the surrounding text, or was just not reproducible at all. Argh.

@james-d-mitchell
Copy link
Contributor

if y'all agree.

Agreed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes topic: error handling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug in interaction of DownEnv, UpEnv, and Where

3 participants