Handling exceptions raised in a Ruby thread

前端 未结 4 1608
陌清茗
陌清茗 2020-12-09 14:49

I am looking for a solution of classic problem of exception handling. Consider following piece of code:

def foo(n)
  puts \" for #{n}\"
  sleep n
  raise \"a         


        
4条回答
  •  南方客
    南方客 (楼主)
    2020-12-09 15:50

    If you want any unhandled exception in any thread to cause the interpreter to exit, you need to set Thread::abort_on_exception= to true. Unhandled exception cause the thread to stop running. If you don't set this variable to true, exception will only be raised when you call Thread#join or Thread#value for the thread. If set to true it will be raised when it occurs and will propagate to the main thread.

    Thread.abort_on_exception=true # add this
    
    def foo(n)
        puts " for #{n}"
        sleep n
        raise "after #{n}"
    end
    
    begin
        threads = []
        [15, 5, 20, 3].each do |i|
            threads << Thread.new do
                foo(i)
            end
        end
        threads.each(&:join)
    
    rescue Exception => e
    
        puts "EXCEPTION: #{e.inspect}"
        puts "MESSAGE: #{e.message}"
    end
    

    Output:

     for 5
     for 20
     for 3
     for 15
    EXCEPTION: #
    MESSAGE: after 3
    

    Note: but if you want any particular thread instance to raise exception this way there are similar abort_on_exception= Thread instance method:

    t = Thread.new {
       # do something and raise exception
    }
    t.abort_on_exception = true
    

提交回复
热议问题