Ruby 手册 | 14 - 异常处理

231 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

一、异常处理

程序运行过程中是无法保证一定不会出错的,如何预见错误并能够正确的处理这些错非常重要,异常处理既程序中的错误处理机制。

Ruby 中的错误处理机制非常简单,当发生错误的时候,会将错误信息打包到一个异常对象中,然后异常对象会自动回溯,直到能找到处理这类异常的代码为止。

Ruby 的异常处理结构由 begin ... rescue ... ensure ... end 形式构成,使用方法如下:

begin
    ... # 正常运行的代码
rescue Exception1
    ... # 处理 Exception1 异常的代码
rescue Exception2 
    ... # 处理 Exception2 异常的代码
rescue => err
    ... # 处理其他错误
ensure
    ... # 这里的代码在发生错误后总是会被执行,可以做一些清理工作
end

Ruby 中的 begin ... rescue ... ensure ... end 类似 Java 中的 try ... catch ... finally 形式,其中 ensure 关键字后的代码无论是否发生错误都一定会执行。

begin
  x = 10
  y = 0
  res = x / y
  puts x
rescue ZeroDivisionError
  puts "除数为 0"
rescue => err
  puts err
ensure
  puts "无论是否发生错误都会执行的代码"
end

执行上述代码,输出结果如下:

除数为 0
无论是否发生错误都会执行的代码

二、抛出异常

有时候可能需要应对一些系统错误之外的错误,这时可以主动抛出异常的功能,使用内核(Kernel)模块中提供的 raise 方法就可以抛出异常。

raise 方法有以下几种用法:

  • raise:简单抛出一个未处理的异常
  • raise "message":抛出一个描述为 message 的异常
  • raise ExceptionType:抛出一个为某种错误类型 ExceptionType 的异常
  • raise ExceptionType:抛出一个某种错误类型 ExceptionType 的异常,并指定错误描述信息

Exception 类是所有 Ruby 异常类的基础,Ruby 中的异常类型也是对象,StandardError 类是所有异常类型的父类。

图片.png

完整的错误类图可以查看源码 StandardError 的继承关系即可,当然在应用中也可以自定义错误类型或者继承已有的异常类型来进行错误处理。

图片.png

三、恢复执行

当发现错误后,进行相应的调整后,程序还可以再次进行运行尝试,在 rescue 块中使用 retry 既可重新执行整个 begin/end 代码块。

x = 10
y = 0

begin
  res = x / y
  puts res
rescue ZeroDivisionError
  y = 2 # 发生错误时将 y 的值重置为 2
  puts "再次尝试运行 begin/end 代码块"
  retry # 再次尝试运行
rescue => err
  puts err
end

执行上述代码,输出结果如下:

再次尝试运行 begin/end 代码块
5

retry 关键字很容易导致程序无限循环运行,使用时要注意。