镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Log a panic in a Rust JSG resource's Drop instead of aborting - #8400

Open
littledivy wants to merge 1 commit into
mainfrom
littledivy/2026-11-12-rjsg-drop-panic-gc
Open

littledivy wants to merge 1 commit into
mainfrom
littledivy/2026-11-12-rjsg-drop-panic-gc

Conversation

@littledivy

Copy link
Copy Markdown
Member

A panic in a Rust JSG resource's Drop aborted the process. The resource is dropped from rust::jsg::Wrappable::~Wrappable, which cppgc runs during its sweep. The cxx bridge turns the panic into a kj::Exception, and throwing it out of the destructor called std::terminate. A panic in a method, by contrast, is caught and becomes a JS internal error. So one bad Drop could take down every isolate in the process.

In this patch ~Wrappable catches the exception and logs it with LOG_EXCEPTION("rustResourceDropPanic", ...), and the process keeps running. Every way a resource is released goes through ~Wrappable, so this covers the GC sweep, the last C++ reference being released and isolate teardown. Rust still drops the remaining fields and frees the allocation while the panic unwinds (std's Rc::drop_slow frees it even when T's destructor panics). The README notes the behaviour.

before after
resource Drop panics during a full GC libc++abi: terminating due to uncaught exception of type kj::Exception error: ... panic in jsg::v8::ffi::wrappable_invoke_drop; sentryErrorContext = rustResourceDropPanic, test passes

Measured with the new panic_in_drop_during_gc_sweep test in //src/rust/jsg-test:jsg-test_test, before and after the change.

Only a path that used to abort changes, and no JS API changes, so this has no compatibility flag.

A panic in a Rust JSG resource's `Drop` aborted the process. The
resource is dropped from `rust::jsg::Wrappable::~Wrappable`, which
cppgc runs during its sweep. The cxx bridge turns the panic into a
`kj::Exception`, and throwing it out of the destructor called
`std::terminate`. A panic in a method, by contrast, is caught and
becomes a JS internal error, so one bad `Drop` could take down every
isolate in the process.

In this patch `~Wrappable` catches the exception and logs it with
`LOG_EXCEPTION("rustResourceDropPanic", ...)`, and the process keeps
running. Every way a resource is released goes through `~Wrappable`,
so this covers the GC sweep, the last C++ reference being released and
isolate teardown. Rust still drops the remaining fields and frees the
allocation while the panic unwinds. The README notes the behaviour.

Only a path that used to abort changes, and no JS API changes, so this
has no compatibility flag.
@littledivy
littledivy requested review from a team as code owners November 12, 2026 16:37

@clanky-the-clanker clanky-the-clanker 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.

✅ Approved — This is a small, well-scoped fix. The destructor catches and logs the exception the cxx bridge turns a Drop panic into, a test covers the GC-sweep path, and no issues were found.

The decision is advisory: this review is a comment and never approves, blocks or requests changes on the pull request.


✅ All checks passed

📋 Code Quality: ✅ LGTM

~Wrappable now wraps wrappable_invoke_drop in kj::runCatchingExceptions and logs a caught exception with LOG_EXCEPTION. The trait object is cleared before drop_rc(), so nothing after the catch depends on the drop having finished. The new code uses only KJ and LOG_EXCEPTION, not C++ JSG. The new test checks that the drop runs exactly once, during the GC sweep.


📝 Documentation: ✅ LGTM

The README paragraph describes the current behaviour accurately: a panic in a resource's Drop is logged and the process keeps running.


Reviewed commit: 1dc056c3

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.

1 participant