Skip to content

Refactor stack traces: named frames, root frame, and builtin collapsing#635

Merged
stephenamar-db merged 2 commits intomasterfrom
error2
Mar 5, 2026
Merged

Refactor stack traces: named frames, root frame, and builtin collapsing#635
stephenamar-db merged 2 commits intomasterfrom
error2

Conversation

@stephenamar-db
Copy link
Collaborator

@stephenamar-db stephenamar-db commented Mar 5, 2026

Summary

Rework error stack traces to produce cleaner, more informative output using the existing Java stack trace mechanism (no custom call stack). This is an alternative to #633 that avoids the performance regression by resolving names at parse time and filtering frames during formatting rather than maintaining a separate call stack.

Key changes

  • Named frames from AST: callTargetName extracts function names from Apply AST nodes at the expression level ([foo], [std.assertEqual], [anonymous]), replacing opaque node type names like [Apply0], [Apply3].

  • Frame filtering: Only Apply* and ApplyBuiltin* expression frames are kept in stack traces, filtering out intermediate AST node types that add noise.

  • Root frame: Every stack trace now includes a [<root>] outermost frame pointing to the top-level expression, injected by Interpreter.evaluateImpl.

  • Builtin error collapsing: When an error originates from inside a builtin's Scala code (e.g., type checking, missing arguments), the builtin name is collapsed into the error message as a prefix rather than shown as a separate frame:

    • sjsonnet.Error: [std.manifestTomlEx] Wrong parameter type: expected Object, got array
    • sjsonnet.Error: [foo] Too many args, has 2 parameter(s)
  • Same-position collapsing: Adjacent frames at the same file position are collapsed to avoid redundant lines.

  • Caused-by chain: formatError now includes Caused by: output for wrapped exceptions (e.g., native function panics).

  • Removed redundant prefixes: "Function " prefix removed from error messages since the frame name now provides that context.

Example outputs

Builtin error (collapsed into message):

sjsonnet.Error: [std.assertEqual] assertEqual failed: {"x":1} != {"x":2}
    at [<root>].(assert_equal4.jsonnet:1:16)

Function parameter error (collapsed):

sjsonnet.Error: [anonymous] parameter x not bound in call
    at [<root>].(bad_function_call.jsonnet:1:16)

Error inside function body (full trace):

sjsonnet.Error: xxx
    at [foo].(error_in_method.jsonnet:1:23)
    at [<root>].(error_in_method.jsonnet:1:7)

Native function panic (with caused-by):

sjsonnet.Error: [std.nativePanic] Internal Error
    at [<root>].(native_panic.jsonnet:1:26)
Caused by: java.lang.RuntimeException: native function panic

Test plan

  • All JVM tests pass (140/140)
  • Golden files regenerated for test_suite, go_test_suite, new_test_suite (340 files)
  • Unit test expectations updated (EvaluatorTests, StdFlatMapTests, StdWithKeyFTests, Std0150FunctionsTests)
  • Native/extvar golden files manually verified (require special test harness args)
  • JS BaseFileTests updated for new format

@stephenamar-db stephenamar-db marked this pull request as draft March 5, 2026 06:29
@stephenamar-db stephenamar-db changed the title [PART 2] Refine stack trace formatting: collapse dispatch frames and name callbacks Refactor stack traces: named frames, root frame, and builtin collapsing Mar 5, 2026
@stephenamar-db stephenamar-db marked this pull request as ready for review March 5, 2026 19:32
Rework error stack traces to use descriptive frame names instead of AST
node type names. Frames now show function names (e.g. [foo], [std.assertEqual])
and always include a [<root>] outermost frame. Builtin errors are collapsed
into the error message prefix when the error originates from Scala code.

Key changes:
- Add callTargetName to extract function names from Apply AST nodes
- Filter frames to only keep Apply/Builtin expression types
- Custom formatError with frame collapsing and "Caused by" chain support
- Remove functionNamePrefix from Val.Func error messages
- Add root frame injection in Interpreter.evaluateImpl
@stephenamar-db stephenamar-db merged commit ad4edb1 into master Mar 5, 2026
8 checks passed
@stephenamar-db stephenamar-db deleted the error2 branch March 5, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant