Skip to content

Deliver exception-construction failures to the timed-out thread - #121

Open
OskarEichler wants to merge 1 commit into
ruby:masterfrom
OskarEichler:codex/errors-timeout
Open

Deliver exception-construction failures to the timed-out thread#121
OskarEichler wants to merge 1 commit into
ruby:masterfrom
OskarEichler:codex/errors-timeout

Conversation

@OskarEichler

Copy link
Copy Markdown

Summary

If Thread#raise fails with a StandardError while constructing/validating the requested exception, deliver that failure to the affected thread instead of letting it terminate the shared watcher. Preserve deferred exception construction for successful operations.

Reproduction

require 'timeout'
broken_error = Class.new(StandardError) do
  def initialize(*)
    raise ArgumentError, 'broken constructor'
  end
end
error = nil
worker = Thread.new do
  Timeout.timeout(0.01, broken_error) { sleep 0.1 }
rescue => e
  error = e
end
worker.join
p error&.class # before: nil; after: ArgumentError

Before this patch the construction error terminates the shared watcher, and an already pending unrelated timeout stops firing too. Bounded concurrent checks reproduce and verify both outcomes with an invalid exception class and a constructor raising ArgumentError. Additional checks confirm normal custom classes/messages and that successful operations still do not construct an exception.

Verification

  • Ruby 4.0.6 via rbenv; reviewed master 295667aac44220ddfd10db014e766ae8d313cfb8.
  • Existing bundle exec rake test: 36 tests / 81 assertions / zero failures or errors, baseline and this branch. Includes the existing signal, fork, Ractor, exception and mocked-scheduler cases.
  • errors: 11 checks, 0 failures in a disposable external script, with the affected expectations reproduced before the change.
  • Syntax and git diff --check pass. Supplemental RuboCop Lint retains the same two existing offenses; no lint-clean claim.
  • No repository tests added/modified, following the consuming project's explicit no-new-tests instruction. Standalone reproduction is included above.
  • Existing issues/PRs checked, including multi threaded use of timeout leads to OOM on high throughput scenarios #58 throughput, Handle nested timeout calls with the same duration #91 nested-timeout draft, Ensure thread is released on completion #114 completed-thread retention, and historic comparison/deferred-exception changes. No duplicate retention or nested-timeout proposal.

Compatibility and limitations

Malformed exception definitions now report their StandardError to the timed operation instead of silently disabling timeouts. Valid timeout exception behavior and deferred construction remain unchanged (including the historical #9354 rationale). This is not a sandbox for arbitrary exception callbacks: SystemExit/other non-StandardError exceptions, blocking constructors or a failure while raising the replacement error are outside this patch.

The same runtime file is shipped in 0.6.1; this patch can be adopted without a release upgrade. Ruby >= 2.6 and the empty runtime dependency set remain unchanged. No production access or external network diagnostic was used; other Ruby/OS combinations and full scheduler implementations were not run locally.

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