Skip to content

🧵🥅 Reraise receiver thread errors with caller's backtrace#691

Merged
nevans merged 3 commits into
masterfrom
reraise-receiver_thread-errors-with-cause-and-local-backtrace
Jun 7, 2026
Merged

🧵🥅 Reraise receiver thread errors with caller's backtrace#691
nevans merged 3 commits into
masterfrom
reraise-receiver_thread-errors-with-cause-and-local-backtrace

Conversation

@nevans

@nevans nevans commented Jun 6, 2026

Copy link
Copy Markdown
Collaborator

Previously, when the receiver thread sent an exception to the client thread, it would be raised with the receiver thread's backtrace, which wasn't very useful.

Now a copy of the exception will be raised, and it will use the current thread's backtrace. If the original has a backtrace or a cause, the original exception will be set as the copy's cause.


There's other work that should be done to normalize receiver thread exception propagation to client threads. But that can wait for another PR (in another release).

@nevans nevans force-pushed the reraise-receiver_thread-errors-with-cause-and-local-backtrace branch from f102688 to 5e7bef4 Compare June 6, 2026 21:50
Comment thread test/net/imap/test_imap.rb Outdated
raise StandardError, "crashy crash"
end
end
assert_reraised(StandardError, imap:) do

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This looks like it might be a flaky test due to a threading race condition. It can either raise this, or it can raise IOError, "stream closed in another thread"

Where it was located implied that it was part of the receiver thread
code.  But, although it does _coordinate_ with that code, it runs purely
in the client thread.
@nevans nevans force-pushed the reraise-receiver_thread-errors-with-cause-and-local-backtrace branch from 5e7bef4 to 051fa8d Compare June 7, 2026 19:48
nevans added 2 commits June 7, 2026 16:33
Previously, when the receiver thread sends an exception to the client
thread, it would be raised with the receiver thread's backtrace, which
wasn't very useful.

Now, a copy of the exception will be raised and it will use
the current thread's `backtrace`.  If the original has a backtrace or a
cause, it will be set as the copy's `cause`.
Calling `Exception#set_backtrace` with `nil` doesn't appear to work for
TruffleRuby 34.0.0.

Issue reported: truffleruby/truffleruby#429

But calling `Exception#set_backtrace` with an array of
`Thread::Backtrace::Location`s wasn't added until ruby 3.4.  Also, minor
difference, but that sets it to the location of `set_backtrace`, not the
location of the `raise`.  (But `caller_locations` drops toe current
frame by default, which is maybe preferable anyway?)
@nevans nevans force-pushed the reraise-receiver_thread-errors-with-cause-and-local-backtrace branch from 051fa8d to 864bb5d Compare June 7, 2026 20:34
@nevans nevans merged commit 4627710 into master Jun 7, 2026
39 checks passed
@nevans nevans deleted the reraise-receiver_thread-errors-with-cause-and-local-backtrace branch June 7, 2026 20:41
@nevans nevans added the enhancement New feature or request label Jul 3, 2026
nevans added a commit that referenced this pull request Jul 3, 2026
An addendum to #691: when `STARTTLS` re-raises a response handler error,
that should be raised with the caller thread's backtrace.  The original
exception will be the cause of the raised exception.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant