feat(wasm-debug-files): Add prepare command for WASM debug setup - #1572
d2anamaria wants to merge 15 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
A deploy |
Sounds like we should, yes. Also a simple warning in this case sounds like the wrong action as we are essentially uploading broken stuff? |
344b5b7 to
cf5ae11
Compare
0fc4d8f to
a408240
Compare
- reuse shared readSourceFile in bundle-sources instead of an inline readFileSync try/catch - build the prepare report by pushing module sections into the summary array instead of spread/flatMap intermediates - name all thirteen non-custom wasm section ids as constants in SECTION_ORDER - trim the prepare docs fragment: drop the wasm-split parity note and shorten the idempotency line
- Move buildIgnoreMatcher into lib/scan/ignore.ts - Reuse it in debug-files prepare and sourcemap commands
loewenheim
left a comment
There was a problem hiding this comment.
On a high level I think this command is misnamed, on two counts:
- It doesn't apply to debug files in general, only wasm.
- "Prepare" doesn't sound like it uploads files, it sounds like something you call before you upload them.
I'm just spitballing, but I could see this as a --split-wasm flag on debug-files upload that splits wasm files with default options (and you can either add options to customize the wasm-split behavior or tell users to run wasm-split manually if they need to customize it).
I agree the name is a bit misleading, but I'd fix the name rather than folding it into upload. This command rewrites your build artifacts, while upload is read-only. Carrying the wasm-split flags over would bloat upload with options that do nothing unless you're uploading wasm. |
|
Yeah, that's fair both on the read-only point and the options point. Again, just a thought: maybe the new command could be folded into |
- name companions <stem>.<build_id>.debug.wasm instead of <stem>.debug.wasm - resolve build id before naming so unstamped modules get unique filenames - write external_debug_info as a path relative to the module, not basename only - dry-run reports exact path when id is known, <build-id> placeholder otherwise - update prepare help text and docs to match the new companion naming
|
…dule - Split the run in two phases: collect companion pointers, then prepare - Step 1 reads only the short header of each section - Step 1 jumps over section contents, so big DWARF files stay fast - Step 1 keeps only a list of companion paths, not file contents - Step 2 reads and splits each module as before - Leave referenced companions untouched, so their DWARF is kept
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ac78128. Configure here.

Problem
Preparing WebAssembly for Sentry takes two tools today. You run
wasm-splitto inject abuild_idand pull DWARF out into a companion file, then runsentry debug-files upload --type wasmon that companion. Nothing tells you when a module was built without usable debug info, so the mistake surfaces later as an unsymbolicated stack trace.Solution
sentry debug-files prepare <path>...does both steps in one command.It scans the given files and directories for
.wasmmodules, splits the ones carrying inline DWARF, and uploads the companions. Org and project are auto-detected from DSN, env vars, or config defaults.--dry-runand--no-uploadneed no credentials.What it does per module
For a module with inline DWARF:
build_idif it has none.*.debug.wasmcompanion keeping every section, including Code and DWARF..debug_*sections from the deployable module, in place.external_debug_info.The deployable keeps its original path, so your build artifact does not move. Both files carry the same
build_id, which is how Sentry matches a stack frame to its debug file. The companion keeps the Code section because DWARF addresses are relative to it.A module that cannot be split is still stamped with a
build_id, then reported with a warning. Stamping matters: without abuild_ida module can never be symbolicated, not even from a debug file uploaded later. Nothing is uploaded for it.build_idalready exists--dry-runpreviewWarnings
A module without usable debug info does not fail the run unless
--require-dwarfis set. The warning says why it was skipped:no line-level symbolication (name/symtab only)no debug information; rebuild with DWARF (Emscripten -g, wasm-pack dwarf-debug-info)already stripped (build_id present, no debug sections); splitting would produce a useless companionhas external_debug_info but no local companion with matching build_idRe-running is safe. An already-prepared pair is detected and left alone rather than overwritten with an empty companion, and a module keeps the
build_idit was stamped with on the first run.Options
--dry-run--no-upload--require-dwarf--out-dir <DIR>--strip-namesnamesection from split deployables; the companion keeps it--build-id <UUID>--include-sources--wait/--wait-for <SECS>--ignore <GLOB>/--ignore-file <FILE>--require-dwarfis the CI guard, and it runs before anything is uploaded, so a build missing debug info fails without pushing files first. A module pointing at an external companion counts as having DWARF, so a dangling pointer does not fail the build.--ignoreglobs are relative to the tree you point at:--ignore 'vendor/**'withprepare ./distmeans./dist/vendor.Scanning rules
Directories are walked recursively.
*.debug.wasmfiles are skipped, since they are outputs of an earlier run. Naming a non-.wasmfile directly is an error; a directory with no modules is just an empty scan.Automation
--jsonreports the outcome per module, so a build script can act on the classification instead of grepping logs:{ "org": "my-org", "project": "my-project", "uploaded": true, "filesUploaded": 1, "modules": [ { "path": "dist/app.wasm", "action": "split", "quality": "dwarf", "buildId": "…", "companion": "dist/app.debug.wasm" } ] }The command exits non-zero when
--require-dwarffails, and when a companion fails server-side processing under--wait.Relationship to wasm-split
sentry wasm-splitsplits one module and stops there. This command is the pipeline around it: itscans directories, classifies each module's debug quality, skips what it should not touch, and
uploads the companions. The split itself is the same
splitWasmcall.Elsewhere the CLI reads debug files through
@sentry/symbolicthat wrapper (only reads).This command rewrites modules: it injects
build_id, strips.debug_*, and addsexternal_debug_info. So it parses sections directly.That is also why the two disagree on
build_id. This command follows the tool convention;symbolicreads it one byte shifted. The id sent here is advisory — the server re-parses the moduleand stores its own key — so nothing breaks today. See
getsentry/symbolic#1069.
Limitations
build_idbut no debug file. Rebuild with DWARF and re-run to get line-level frames; thebuild_idis preserved.external_debug_inforecords the companion filename only.preparedoes not exposewasm-split's--external-dwarf-url; reach forsentry wasm-splitif you need a custom URL. Sentry resolves bybuild_id, so this does not affect symbolication.--out-dir, re-running without the same--out-dirwill not find the companion and reports a dangling reference.