处理ruby中的默认异常

时间:2013-07-06 13:23:33

标签: ruby exception

如何实现异常的默认行为? begin rescue else不起作用(我认为应该这样做)。

而且,情景中else是否毫无意义?在没有引发异常时必须运行的任何代码都在begin-rescue块之间运行。

顺便提一下,我有以下解决方法,但我对此并不满意。

class MyException < Exception
end

class YourException < Exception
end

begin
  raise MyException if 2 > 50
  raise YourException if 1 < 90
rescue Exception => e
  case e.message
  when /MyException/
    puts "MyException Caught"
  else
    puts "Default Exception Caught"
  end
end

2 个答案:

答案 0 :(得分:5)

首先,你真的不应该是Exception的子类。它是所有 Ruby异常的超类,包括NoMemoryErrorSyntaxErrorInterruptSystemExit;所有这些你通常不需要拯救。不管是意外还是故意这样做都是不鼓励的,因为它可以防止程序正常退出,即使它被用户中断也是如此。它还可以隐藏或产生一些非常模糊的错误。

你想要子类化的是StandardError,它是我们在日常编程中看到的大多数Ruby错误的超类。如果你没有指定一个类,那么这个类也是rescue d:

begin
  object.do_something!
rescue => error    # will rescue StandardError and all subclasses
  $stderr.puts error.message
end

我相信这是您正在寻找的“默认行为”。您可以处理特定错误,然后处理所有其他错误:

class CustomApplicationError < StandardError
end

begin
  object.do_something!
rescue CustomApplicationError => error
  recover_from error
rescue => error
  log.error error.message
  raise
end

else子句在错误处理中没有任何意义。当且仅当没有引发异常时,它将执行嵌套代码,而不管是否将执行代码的ensure子句。它允许您处理成功案例。

begin
  object.do_something!
rescue => error
  log.error error.message
else
  log.info 'Everything went smoothly'
end

答案 1 :(得分:1)

首先,我不明白你为什么要使用错误信息进行病例调节。为什么不通过他们的班级错误本身呢?然后,它会是这样的:

begin
  raise MyException if 2 > 50
  raise YourException if 1 < 90
rescue Exception => e
  case e
  when MyException
    puts "MyException Caught"
  else
    puts "Default Exception Caught"
  end
end

其次,如上所述并不是直截了当的方式。正确的方法是:

begin
  raise MyException if 2 > 50
  raise YourException if 1 < 90
rescue MyException
  puts "MyException Caught"
rescue Exception
  puts "Default Exception Caught"
end

如果YourExceptionStandardError的子类,那么rescue可以捕获它而不指定异常类。