Skip to content

fix(run): preserve script stdout when an Upload-and-Run file fails - #2171

Merged
rugpanov merged 2 commits into
mainfrom
feat/stream-stdout-on-error
Sep 4, 2026
Merged

fix(run): preserve script stdout when an Upload-and-Run file fails#2171
rugpanov merged 2 commits into
mainfrom
feat/stream-stdout-on-error

Conversation

@rugpanov

@rugpanov rugpanov commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Problem

When running a Python file on a cluster ("Upload and Run File"), if the script raises an exception, any output it printed before failing is lost. The 1.2/commands execution API returns only the traceback on an error result and drops the accumulated stdout, so the output panel shows the traceback with none of the preceding print output — making failures hard to debug.

Fix

Because a single command yields a single result whose error variant has no stdout field, the captured output has to be preserved where it still exists — in the bootstrap that runs the file.

  • resources/python/bootstrap.py buffers the script's stdout while it runs. On an exception that follows printed output, it emits the captured stdout, a boundary marker, then a structured JSON traceback containing only the user's frames. Errors with no prior output re-raise unchanged; successful runs and SystemExit/KeyboardInterrupt replay the buffer, so no output is lost.
  • src/run/ErrorParser.ts adds renderErrorEnvelope() to turn that JSON payload into renderable frames (red-highlighted summary line), plus a shared boundary constant.
  • src/run/DatabricksRuntime.ts splits the text result on the boundary — emitting the stdout first, then the traceback remapped to local files (so frames stay clickable) — and shares the frame-emit logic between the new path and the existing error path.

The new behaviour triggers only on print-then-crash. Successful runs and errors with no prior output render exactly as before.

Verification

  • yarn build (full tsc) clean; eslint and prettier clean; bootstrap.py compiles.
  • Unit tests 4/4 pass (2 new for renderErrorEnvelope).
  • End-to-end against a live cluster running the real bootstrap.py:
    • print-then-crash → stdout preserved, followed by a clickable traceback with only the user frame;
    • success + output → plain text output, unchanged;
    • error with no prior output → native error result, unchanged.

This pull request and its description were written by Isaac.

*Why*
When running a Python file on a cluster ("Upload and Run File"), if the
script raised an exception, any output it printed before failing was lost:
the 1.2 commands API returns only the traceback on an error result and
drops the accumulated stdout. Users saw the traceback with none of the
preceding print output, which makes failures hard to debug.

*What*
- bootstrap.py now buffers the script's stdout while it runs. On an
  exception that follows printed output, it emits the captured stdout, a
  boundary marker, then a structured JSON traceback (user frames only).
  Errors with no prior output re-raise unchanged; success and SystemExit
  replay the buffer, so no output is lost.
- ErrorParser.ts gains renderErrorEnvelope() to turn that JSON payload
  into renderable frames, plus a shared boundary constant.
- DatabricksRuntime.ts splits the text result on the boundary (stdout
  first, then the remapped, clickable traceback) and shares the frame-emit
  logic between the new path and the native error path.

The new behaviour triggers only on print-then-crash; successful runs and
errors with no prior output render exactly as before.

*Verification*
- yarn build (tsc) clean; eslint and prettier clean; bootstrap.py compiles.
- Unit tests 4/4 pass (2 new for renderErrorEnvelope).
- End-to-end on a live cluster: print-then-crash preserves stdout and shows
  a clickable traceback; success and no-output errors are unchanged.

Co-authored-by: Isaac <no-reply@databricks.com>
@rugpanov
rugpanov deployed to test-trigger-is September 3, 2026 13:36 — with GitHub Actions Active
@rugpanov
rugpanov deployed to test-trigger-is September 3, 2026 13:37 — with GitHub Actions Active
@rugpanov
rugpanov deployed to test-trigger-is September 3, 2026 13:37 — with GitHub Actions Active
@rugpanov

rugpanov commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ✅ all 41 test jobs passed for f039406c.
View run

@rugpanov
rugpanov enabled auto-merge (squash) September 4, 2026 09:42
@rugpanov
rugpanov deployed to test-trigger-is September 4, 2026 09:42 — with GitHub Actions Active
@rugpanov
rugpanov merged commit 05ebc1c into main Sep 4, 2026
6 checks passed
@rugpanov
rugpanov deployed to test-trigger-is September 4, 2026 09:44 — with GitHub Actions Active
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/vscode

Inputs:

  • PR number: 2171
  • Commit SHA: 4b846d4b52cdd591a9576059b7fadf417541a5d1

Checks will be approved automatically on success.

@rugpanov
rugpanov deployed to test-trigger-is September 4, 2026 09:44 — with GitHub Actions Active
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.

2 participants