Skip to content

console.table: propagate errors thrown while printing the table - #37402

Open
robobun wants to merge 1 commit into
mainfrom
farm/4dbf41e8/console-table-propagate
Open

console.table: propagate errors thrown while printing the table#37402
robobun wants to merge 1 commit into
mainfrom
farm/4dbf41e8/console-table-propagate

Conversation

@robobun

@robobun robobun commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

What

message_with_type_and_level_ wrote let _ = table_printer.print_table(...) and returned Ok(()), discarding the JsResult.

console.table([{ get x() { throw new Error("boom"); } }]);

When a getter, Proxy trap or custom inspect hook throws while the cells are read, print_table returns Err(Thrown) with the exception pending on the VM, and the host function still reported success. The exception did reach JS through the pending-exception path, but the function's return value disagreed with the VM state, and an Err(OutOfMemory) from the printer was dropped outright (no exception raised at all, since it is the caller's job to throw it).

Fix

Return the print_table result from the table branch (still flushing the writer first), so the outer message_with_type_and_level handles it like every other error from this function. Bun.inspect.table already propagates the same result.

Tests

test/js/bun/console/console-table.test.ts: console.table with a throwing getter, a throwing Proxy ownKeys trap and a throwing custom inspect hook rethrows the original error, and a script hitting it prints nothing to stdout and exits 1. These lock in the behaviour; they pass before this change as well, since the thrown case already surfaced via the pending exception.

message_with_type_and_level_ discarded the JsResult returned by
TablePrinter::print_table, so a getter, Proxy trap or custom inspect
hook that threw while the cells were being read left the exception
pending on the VM while the host function reported success, and an
OutOfMemory result was dropped without any exception being raised.
Return the result instead, which lets the caller raise the OOM error
and keeps the function's return value consistent with the VM state.

Adds console.table coverage for throwing getters, Proxy traps and
custom inspect hooks, including that nothing is printed.
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

console.table now preserves and returns errors from table printing after flushing. Tests cover getter, Proxy, custom inspector, and uncaught subprocess failures.

Changes

console.table error handling

Layer / File(s) Summary
Propagate and validate table errors
src/jsc/ConsoleObject.rs, test/js/bun/console/console-table.test.ts
console.table returns the result from TablePrinter::print_table after flushing. Tests verify exception propagation, stderr output, empty stdout, and exit status 1.

Possibly related PRs

Suggested reviewers: jarred-sumner

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely states that console.table now propagates errors from table printing.
Description check ✅ Passed The description explains the problem, fix, affected errors, and tests, but uses different headings from the repository template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/jsc/ConsoleObject.rs`:
- Line 510: Update the flush handling in print_table so a successful print_table
followed by writer.flush() failure returns the flush error instead of discarding
it. Preserve any print_table error as the primary returned error.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 55f3417c-b917-45e6-8cf3-7bc272d47a7d

📥 Commits

Reviewing files that changed from the base of the PR and between 9fcdea8 and 3f1e37b.

📒 Files selected for processing (2)
  • src/jsc/ConsoleObject.rs
  • test/js/bun/console/console-table.test.ts

Comment thread src/jsc/ConsoleObject.rs

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — trivially correct JsResult propagation, matching every other error path in this function.

Extended reasoning...

Overview

Two-file change: src/jsc/ConsoleObject.rs stops discarding print_table's JsResult in the console.table branch (still flushing the writer first), and test/js/bun/console/console-table.test.ts adds four tests locking in that exceptions from getters / Proxy traps / custom-inspect hooks propagate out of console.table.

Security risks

None. This only changes whether an already-pending JS exception's error state is reflected in the Rust return value (and whether an Err(OutOfMemory) from the printer gets converted to a thrown OOM by the outer wrapper). No new inputs, no new I/O.

Level of scrutiny

Low. The outer message_with_type_and_level at src/jsc/ConsoleObject.rs:361-368 already handles Err(Thrown) (no-op, exception pending) and Err(OutOfMemory) (calls throw_out_of_memory_value); TablePrinter::init(...)? on line 502 and the Dir branch's opts.get(...)? calls already propagate through the same path, so this change just brings the print_table call in line with its siblings. The let _ = writer.flush() before the return matches the existing pattern at lines 429-430. Bun.inspect.table already propagates the same result, so the Node/WHATWG-facing behavior was already established.

Other factors

The inline nit is informational: the author is upfront in the PR description that the new tests pass before and after the Rust change (the Thrown case already surfaced via the pending-exception slot; only the untestable-from-JS OutOfMemory case is observably different). The tests are still useful regression coverage for the throw contract, and the Rust change is obviously correct on inspection — "don't discard a JsResult" needs no further justification. Test structure follows harness conventions (bunExe()/bunEnv, await using on the spawn, concurrent pipe drain, exitCode asserted last).

Comment thread test/js/bun/console/console-table.test.ts
@robobun

robobun commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 9:34 PM PT - Aug 10th, 2026

@robobun, your commit 3f1e37b8ae642f1e14604ff55fd7de58c6e44ed1 passed in Build #91908! 🎉


🧪   To try this PR locally:

bunx bun-pr 37402

That installs a local version of the PR into your bun-37402 executable, so you can run:

bun-37402 --bun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants