1

如何实现异常的默认行为?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
4

2 回答 2

5

First of all, you really shouldn't subclass Exception. It is the superclass of all Ruby exceptions, including NoMemoryError, SyntaxError, Interrupt, SystemExit; all of which you don't normally need to rescue from. Doing so, whether accidentally or on purpose, is discouraged since it can prevent a program from exiting properly, even if it was interrupted by the user. It can also hide or produce some quite obscure bugs.

What you want to subclass is StandardError, which is the superclass of most Ruby errors we see in day-to-day programming. This class is also the one which will be rescued should you not specify one:

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

I believe this is the "default behavior" you are looking for. You can handle a specific error, then all other errors in general:

class CustomApplicationError < StandardError
end

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

The else clause is not meaningless in error handling. It will execute the nested code if and only if no exceptions were raised, as opposed to the ensure clause which will execute code regardless. It allows you to handle success cases.

begin
  object.do_something!
rescue => error
  log.error error.message
else
  log.info 'Everything went smoothly'
end
于 2013-07-06T13:46:06.327 回答
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

如果YourException是 的子类StandardError,则可以在rescue不指定异常类的情况下捕获它。

于 2013-07-06T14:53:01.600 回答