From: ale@... Date: 2001-08-16T04:03:57+09:00 Subject: [ruby-talk:19823] Re: Exception handling bug? Sorry, about the long post... On Thu, 16 Aug 2001, Dave Thomas wrote: > Dave Thomas writes: > > > ale@crimson.propagation.net writes: > > > > > Didn't post this to the bug database, as I'm not completely > > > sure this is a bug. But let's see what you think about it. > > > ... and to followup my own post, the unqualified rescue clause is also > swallowing the timeout. Yep, Dave was right. There was no bug, just consistent behaviour. The "bug" could be essentially explained here timeout(x) do # loop ensures we spend enough time in here loop do begin do_something rescue # rescues _everything_ including the thrown TimeoutError (*) end end end So when the TimeoutError is finally after x seconds thrown, it's rescued and loop continues on, never letting out from timeout call. This version works timeout(x) do loop do begin do_something rescue TimeoutError => te # pass the TimeoutError out of loop do..end to timeout raise te rescue end end end But now, the current design of timeout library doesn't allow one to timeout arbitrary code, as the code's normal exception handling can interfere with the timeouting exception. Thus, the solutions are at least: 1) write rescue TimeoutError => te; raise te; everywhere (This is called, I believe, defensive programming, and it's easy to understand why one doesn't want to tweak each exception handling, just because it's possible that the code will be timeouted sometime.) 2) alter timeout.rb So, I propose a RCR for this one. RCR#U024 Problem: A code which has not been designed timeouting library in mind, won't work perfectly when it contains not fully qualified rescue-clauses. Proposed solution: A change in timeout.rb of standard library to derive class TimeoutError < Interrupt end instead of from StandardError. The change would make an exception raised at timeout to skip common "catch-all" rescue-clause. An example: timeout(x) do # loop ensures we spend enough time in here loop do begin do_something rescue # rescues StandardError, but should not # for example TimeoutError end end end Previously the example hangs, with above fix it won't. Possible effects on current code base: Most of the code would not suffer at all, and some code might work even better than before. Code that depends on TimeoutError being a descendant of StandardError wouldn't work anymore, neither code which assumes plain begin .. rescue .. end to capture also TimeoutErrors. Things to decide: Is the Interrupt really the best place to derive from? Should Exception be used instead, or something else? - Aleksi Ps. the RCR is also at wiki http://www.rubygarden.org/ruby?NeedDiscussion