Skip to content

fix(exception): raise try-nesting limit to 1024 to avoid process abort#5071

Merged
proggeramlug merged 2 commits into
mainfrom
fix/try-depth-limit
Jun 13, 2026
Merged

fix(exception): raise try-nesting limit to 1024 to avoid process abort#5071
proggeramlug merged 2 commits into
mainfrom
fix/try-depth-limit

Conversation

@TheHypnoo

@TheHypnoo TheHypnoo commented Jun 13, 2026

Copy link
Copy Markdown
Member

What

Raises MAX_TRY_DEPTH from 128 to 1024 in crates/perry-runtime/src/exception.rs.

Why

js_try_push stores per-thread try state in fixed-size arrays of length 128 and panic!s (aborting the whole process) on the 129th simultaneously-active try frame. Legal TypeScript — e.g. a recursive function whose body is wrapped in try/catch (recursive-descent parser, tree walker) — could hit this and crash, where Node.js keeps running. Raising the cap to 1024 removes the realistic failure cases; genuinely unbounded recursion hits a native stack overflow well before 1024 nested setjmp frames anyway.

Notes

  • The arrays stay fixed-size (no allocation, const fn initializer preserved) — lowest-risk change. JmpBuf is 256 B, so jump_buffers grows to ~256 KB per OS thread; ShadowSavepoint is 16 B (verified). Converting the overflow into a catchable RangeError was considered but deliberately deferred as higher-risk.

Test

New unit test try_push_pop_beyond_old_limit_does_not_panic pushes >128 frames and unwinds without panic. cargo test -p perry-runtime exception → green.

Closes #5065

Summary by CodeRabbit

  • Bug Fixes

    • Increased maximum nesting depth for try blocks from 128 to 1024, allowing applications to use deeper exception handling structures without hitting limits.
    • Expanded documentation to clarify the new nesting depth limit and previous constraints.
  • Tests

    • Added regression tests verifying the new limit works correctly and properly tracks nesting depth.

@TheHypnoo TheHypnoo self-assigned this Jun 13, 2026
@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR raises the maximum try-block nesting depth from 128 to 1024 and adds a regression test. The constant is updated with expanded documentation explaining the new TLS sizing expectations, and a new test validates that deeply nested try frames no longer panic the process.

Changes

Try Block Nesting Depth Increase

Layer / File(s) Summary
Increase MAX_TRY_DEPTH constant and documentation
crates/perry-runtime/src/exception.rs
The MAX_TRY_DEPTH constant is raised from 128 to 1024 with updated documentation explaining the new sizing rationale and prior abort behavior at the old limit.
Regression test for deep try nesting
crates/perry-runtime/src/exception.rs
A regression test exercises js_try_push and js_try_end beyond the old 128-frame cap, asserting no panic occurs, frames are correctly pushed/popped, and current_try_depth() is properly incremented and decremented.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 Deep nesting paths now soar so high,
From one-two-eight to ten-two-four!
Try-frames stack without a sigh,
No panics here, we've fixed the flaw. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: raising the try-nesting limit from 128 to 1024 to prevent process abort, which directly matches the core modification in the changeset.
Description check ✅ Passed The PR description provides a clear summary of what changed and why, includes detailed technical context, notes on implementation decisions, and test coverage, though it lacks explicit checkboxes completion status.
Linked Issues check ✅ Passed The PR successfully addresses issue #5065 by raising MAX_TRY_DEPTH to 1024 and adding a regression test that validates try frames beyond the old 128 limit do not panic, meeting the stated acceptance criteria.
Out of Scope Changes check ✅ Passed All changes are scoped to the exception handling system: MAX_TRY_DEPTH constant update, comment expansion, and a focused regression test—no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/try-depth-limit

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
crates/perry-runtime/src/exception.rs (1)

417-438: 💤 Low value

Regression test correctly validates deep try nesting.

The test properly exercises the fix by pushing >128 try frames and verifying no panic occurs. The relative depth calculation (base = current_try_depth()) makes it robust under shared TLS when tests run sequentially.

Minor note: The assertion pushes > 128 (lines 425-428) assumes base is small enough to leave room for >128 additional frames. In practice this holds because the other test in this module cleans up properly, but the assertion could theoretically fail if base >= 895. Consider adding a comment explaining this assumption, or using assert!(pushes > 128 || base > 0, "...") to make the constraint explicit.

🤖 Prompt for 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.

In `@crates/perry-runtime/src/exception.rs` around lines 417 - 438, The assertion
in test try_push_pop_beyond_old_limit_does_not_panic assumes base (from
current_try_depth()) leaves room for >128 additional frames and could
theoretically fail if base is large; update the test to make the assumption
explicit by either adding a clarifying comment near the pushes > 128 check
referencing current_try_depth()/MAX_TRY_DEPTH, or change the assertion to
something like assert!(pushes > 128 || base > 0, "expected room for >128 frames
beyond the old limit or nonzero base"), so the test documents/handles the edge
case while still validating js_try_push and current_try_depth behavior.
🤖 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.

Nitpick comments:
In `@crates/perry-runtime/src/exception.rs`:
- Around line 417-438: The assertion in test
try_push_pop_beyond_old_limit_does_not_panic assumes base (from
current_try_depth()) leaves room for >128 additional frames and could
theoretically fail if base is large; update the test to make the assumption
explicit by either adding a clarifying comment near the pushes > 128 check
referencing current_try_depth()/MAX_TRY_DEPTH, or change the assertion to
something like assert!(pushes > 128 || base > 0, "expected room for >128 frames
beyond the old limit or nonzero base"), so the test documents/handles the edge
case while still validating js_try_push and current_try_depth behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a18667b4-68ef-4bac-b19a-bfab01b48d38

📥 Commits

Reviewing files that changed from the base of the PR and between ab5b7e8 and d263a2b.

📒 Files selected for processing (1)
  • crates/perry-runtime/src/exception.rs

@proggeramlug proggeramlug merged commit a9c67fa into main Jun 13, 2026
14 checks passed
@proggeramlug proggeramlug deleted the fix/try-depth-limit branch June 13, 2026 10:13
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.

try/catch nesting deeper than 128 panics the process instead of throwing

2 participants