Skip to content

Pass an Exception to #raise#643

Merged
nevans merged 4 commits intoruby:masterfrom
eregon:raise-pass-exception
Apr 17, 2026
Merged

Pass an Exception to #raise#643
nevans merged 4 commits intoruby:masterfrom
eregon:raise-pass-exception

Conversation

@eregon
Copy link
Copy Markdown
Member

@eregon eregon commented Apr 17, 2026

  • Fixes TypeError: exception class/object expected on truffleruby because #raise with a non-Exception non-String is not supported currently on TruffleRuby.

Unfortunately it seems #642 broke on TruffleRuby and because of ruby/test-unit-ruby-core#23 it wasn't noticed.

In this PR I do an easy fix for this failure.
However after that the test suite still fails with a timeout.

I also tried increasing the timeout (from 10 to 100 commit) but it did not help.
When that test is run in isolation (bundle exec ruby -Itest/lib -rhelper test/net/imap/test_imap_max_response_size.rb) it works fine though, so it sounds like there is some global state/side effect that makes the test fail somehow when run as part of the full test suite.

I don't have time to investigate more now, maybe I can take another look in the evening.

* Fixes `TypeError: exception class/object expected` on truffleruby
  because #raise with a non-Exception non-String is not supported currently on TruffleRuby.
Comment thread lib/net/imap/response_reader.rb Outdated
def guard_response_too_large! = (raise self if response_too_large?)
def guard_response_too_large! = (raise exception if response_too_large?)

def exception(msg = nil)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't know the intention but it sounds unusual to implement #exception on non-Exception objects.
It means e.g. users could do raise someNet_IMAP_ResponseReader_instance but I would think very few would expect to work, they would expect an error because it's raising something which isn't an Exception.

So maybe this method should be inlined in its only caller, like before #642?

Copy link
Copy Markdown
Collaborator

@nevans nevans Apr 17, 2026

Choose a reason for hiding this comment

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

Yeah, I was getting way too cute with that one! 🤣 I just did it that way in passing, without thinking very much of it, and I'd completely intended to replace it before merging! I do like the idea of relying on #exception duck-typing, where it makes sense semantically. But... it does not make semantic sense here.

Copy link
Copy Markdown
Collaborator

@nevans nevans Apr 17, 2026

Choose a reason for hiding this comment

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

Another refactoring branch (with a more substantial change to mitigate against pathological performance issues) was raising the same exception from multiple places. I extracted that and named it #exception as a temporary placeholder. But I discovered a more significant performance improvement at the same time. So it accidentally migrated into into this branch after a few rebase/cherry-pick rearrangements. 😳

nevans
nevans previously approved these changes Apr 17, 2026
It's only called from one place.  And `#exception` isn't the right name
for that method anyway.
nevans
nevans previously approved these changes Apr 17, 2026
Copy link
Copy Markdown
Collaborator

@nevans nevans left a comment

Choose a reason for hiding this comment

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

I actually ran the tests before pushing, this time. 😳

Hopefully truffleruby will pass with this?
@nevans
Copy link
Copy Markdown
Collaborator

nevans commented Apr 17, 2026

I wasn't triggering that timeout locally, but since I now know about EnvUtil.timeout_scale (😉), I've used it on FakeServer.

@nevans
Copy link
Copy Markdown
Collaborator

nevans commented Apr 17, 2026

Hmm.. no. I think this may actually be due to 0e89dbb!

This test was broken by 0e89dbb, which
changed the semantics of when `max_response_size` takes effect.  But
it's a race condition, so TruffleRuby was hitting it frequently, and I
hadn't seen it in CRuby yet.
@nevans nevans force-pushed the raise-pass-exception branch from d993bfa to 236832f Compare April 17, 2026 13:58
@nevans
Copy link
Copy Markdown
Collaborator

nevans commented Apr 17, 2026

Yes, it was due to 0e89dbb. I'd forgotten that I'd added a test for the original behavior.

And now I'm second-guessing whether I want that behavior change to go out in an x.y.z point release... But I think I'm going to stick with my original rationale: the original behavior was already non-deterministic. And, where exactness is required, the correct approach was always to either make the update it in a response handler, or simply trigger a response (i.e: with noop)

@nevans nevans merged commit 3e29393 into ruby:master Apr 17, 2026
17 checks passed
@eregon
Copy link
Copy Markdown
Member Author

eregon commented Apr 17, 2026

Great, thank you for the fixes!

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