Name the call site in non-Gleam crash reports - #10
Merged
Merged
Conversation
A test that died with a non-Gleam error reported only the bare reason:
a stale filepath.beam shadowing the filepath package turned every test
in a module into an information-free "Crashed: Undef". The M:F/A that
identifies the failure was in the stacktrace's top frame, discarded by
catch_panic.
catch_panic now captures the stacktrace and returns {Reason, Stacktrace}
- deliberately the shape BEAM exit reasons already have, so one
split_crash/1 serves both the caught-panic and process-death paths.
Classification reduces the trace to a CrashSite (module, function,
arity, file/line when the frame carries them) on UnknownDetail and
ExitDetail, keeping the inspectable reason free of frame dumps.
The console reads "Crashed: Undef calling config_parser:parse/1" with an
"at file:line" line when known; TeamCity and JUnit messages carry the
same summary via describe.crash; JSONL gains site_* fields mirroring the
todo outcome's naming. JavaScript is unchanged - a JS stacktrace is an
unparsed string, so there is never a site and the fallback wording is
pinned by spec.
The playground gains crashing_config_test (undef on the BEAM, a raw
TypeError on JavaScript, where a missing module would break discovery
at import time), and the e2e suite asserts the site fields through the
subprocess JSONL stream on both targets.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Crash reports from processes the tests spawned (and anything else routed through OTP's logger) used to hit stderr asynchronously, interleaving with test output — and in watch mode straddling the inner run's frame — or getting lost entirely when the VM halted first. vouch_ffi now doubles as a logger handler: it replaces the default handler, renders each event with the formatter the default handler would have used, and stashes the text in ETS. The runner drains the table after the run summary and reprints everything as one stderr block, so stdout stays machine-clean and nothing is lost at halt. If the handler cannot be installed, the old redirect-to-stderr remains as the fallback. take_diagnostics_matching lets the suite's deliberately-crashing specs (linked crash, gen_server todo) assert their reports were captured and consume them, keeping vouch's own run tail clean without racing other tests under --parallel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
linked_undef_crash_names_call_site_test leaks a linked process that dies with undef, so its emulator report showed up as a stray diagnostic at the end of the vouch test run. Assert it was captured and consume it, matching the other crash-generating specs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A process that dies under a test is already reported through the test outcome; the BEAM crash report of the same death is a duplicate, and for OTP actors it is sixty lines each. Keep the capture handler (it is what stops the reports reaching stderr) and drop the end-of-run block. take_diagnostics_matching stays so the suite can prove the reports are captured rather than printed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Crash reports are swallowed by default; this flag prints the captured reports as one block on stderr after the summary, for when the full BEAM report is wanted. Warned as ineffective on the JavaScript target, like --timeout and --parallel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A test that dies with a non-Gleam error reports only the bare reason. The motivating real-world case: a stale
filepath.beamshadowing thefilepathpackage turned every test in one module into an information-freeCrashed: Undef. The M:F/A identifying the failure was sitting in the stacktrace''s first frame -{filepath, split, [<<"gleam.toml">>], []}- butcatch_panicdiscarded__STACKTRACE__, so nothing downstream could report it.Change
catch_paniccaptures the stacktrace and returns{error, {Reason, Stacktrace}}- deliberately the same shape as BEAM exit reasons, so a singlesplit_crash/1serves both the caught-panic and process-death classification paths.find_panic''s recursive tuple search keeps Gleam-panic decoding working through the extra tuple (guarded by the existing OTP-wrapping spec).split_crash/1reduces the trace to aCrashSite(module, function, arity, file/line when the frame carries them);UnknownDetailandExitDetailcarry it asOption(CrashSite). The inspectable reason stays stacktrace-free, so no reporter ever dumps raw frames.Crashed: Undef calling config_parser:parse/1, plus anat file:linesecond line when the frame has a location (undef frames never do - the function does not exist). TeamCity and JUnit embed the same summary via a shareddescribe.crash; JSONL gains structuredsite_module/site_function/site_arity(plussite_file/site_line) fields mirroring the todo outcome''ssite_*naming.Coverage
crashing_config_test- undef on the BEAM, a TypeError-throwing FFI on JavaScript (the module must exist there: a missing .mjs import would break discovery of the whole suite at import time).Both targets green: 80 passed (Erlang, including the four e2e subprocess runs), 67 passed (JavaScript).
🤖 Generated with Claude Code