Commit 3f46d56
fix(sdk): select stack-trace frames by SDK boundary instead of fixed depth (#1599)
## Description
Template build stack traces were captured by walking a fixed number of
frames (`STACK_TRACE_DEPTH` plus `±1` arithmetic at ~15 call sites),
which broke whenever the frame count between `new Error()` and user code
shifted — TS class-field initializer frames (#1539) and Bun's tail-call
frame elision were both this bug. This PR makes two related changes:
1. **Boundary-based frame selection.** The caller's frame is now the
first one whose file lies outside the SDK package, making extra
transpiler frames and elided delegating frames irrelevant. In the JS
SDK, frame parsing is delegated to `error-stack-parser-es` (ESM-only, so
it's a devDependency inlined into both dist formats via tsdown
`noExternal` — the engines range includes Node versions without
`require(esm)`); the Python SDK equivalently walks `f_back` until
`co_filename` leaves the `e2b` package root, in the shared builder used
by both sync and async. If no user frame is identifiable (e.g. the SDK
is bundled into the caller's own file), capture degrades to no trace
rather than a wrong frame.
2. **Dead machinery removed.** Because boundary capture resolves through
SDK-internal delegation (`remove()` → `runCmd()`, `fromDockerfile()` →
parser) to the user's call site on its own, the suppress/override
collection machinery (`runInNewStackTraceContext`,
`runInStackTraceOverrideContext`, the enabled/override flags, and their
Python equivalents) became redundant and is removed — superseding the
approach in #1596.
Error `.stack` synthesis (keeping the `Name: message` header and the
throw site on `cause`) was prototyped here and backed out — it will come
as a follow-up PR.
## Usage
No API changes — build errors now point at the user's call site
regardless of runtime or transpiler:
```ts
const template = Template()
.fromBaseImage()
.runCmd('./does-not-exist') // ← build failures point exactly here
await Template.build(template, 'my-template')
```
## Testing
- JS: `unit` + `template` vitest projects green against the real API
(incl. 27 per-method stacktrace tests pinning exact call-site
line/columns, `bunInstall` now covered); edge-compat bundle test and CLI
build verified; built CJS/ESM dists smoke-tested with
`require()`/`import()`.
- Python: all 184 template tests green (shared + sync + async, incl.
both `test_stacktrace.py` suites, `bun_install` now covered); `ruff` and
`ty` clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 00253c3 commit 3f46d56
15 files changed
Lines changed: 289 additions & 393 deletions
File tree
- .changeset
- packages
- js-sdk
- src/template
- tests/template
- utils
- python-sdk
- e2b/template
- tests
- async/template_async
- sync/template_sync
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| 59 | + | |
59 | 60 | | |
60 | 61 | | |
61 | 62 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | 15 | | |
30 | 16 | | |
31 | 17 | | |
| |||
0 commit comments