2.5. 核心语言——错误处理

未匹配的标注

Ruby 使用异常来处理错误。

Raise关键字

Raise 这个关键字后面跟的就是错误类型的名字,还有一个 message 紧接着就抛出这个错误。Raise 它会终止当前的方法以及调用这个的方法。然后在堆栈里依次往上,直到一个 rescue 子句出现。

raise NameError, "that's not my name"

image-20221003222217676

begin 和 rescue 关键字

为了捕获潜在的异常,使用 begin 和 rescue 关键字。这个结构就跟其他语言里面你可能遇到的 try/catch 指令是差不多的,它是从 begin后的指令开始运行,直到其中一个指令产生异常。如果异常发生,这个时候 rescue 这个区块就将被执行。

begin 
  set_name('jim')
rescue
  puts "sth bad happened"
end

image-20221003222249781

rescue + 箭头 + 变量

你可以在 rescue 的后面选择性的加一个箭头和变量,这个时候异常对象就将绑定到这个变量上。

begin
  set_name("Jim")
rescue => error
  puts error.message
end

image-20221003222330376

rescue + 错误类型名称 + 箭头 + 变量

rescue 还可以跟错误类型的名称,然后 Ruby 将根据异常与每个 rescue 子句后的错误类型进行匹配的结果,来决定执行哪个区块。

begin
  set_name("Jim")
rescue NameError => error
  puts "bad name: #{error.message}"
rescue TypeError => error
  puts "bad type: #{error.message}"
end

image-20221003222416561

方法体中,begin 和 end 可以省略

在一个方法体中(我们这个 def 和 end 之间就是方法体),变量处理的 begin 和 end 都是可以省略的。如果一个方法体包含了一个 rescue 子句,那么它就表现得像整个方法体已经被 begin 和 end 包裹了一样。

def foo
  do_something(x)
rescue => e
  handle_error(e)
end

foo

image-20221003222526161

retry 关键字

在一个 rescue 子句里面,如果还含有 retry 这个关键字,就会使 begin 这一部分重新从头执行。

begin
  set_name("Jim")
rescue
  puts "something bad happened"
  retry
end

这个会不停执行 begin 区块,就不演示了

ensure 子句

在错误处理区块中,除了 rescue 子句外还可以包括 ensure 子句——类似于其他语言中的 Finally,这里面定义了不管是否有错误抛出都会被执行的代码,对清理资源是很有用的。

begin
  file = File.open("config.json")
  config = JSON.parse(file.read)
rescue
  puts "invalid JSON"
ensure
  file.close
end

image-20221003222649433

Ruby 内置错误对象

Ruby 还有很多内置的错误对象以及库的自定义错误。 Errno 模块就定义了各种代表底层 C 系统代码中的低级错误的错误。比如如果你打开一个并不存在的文件,一个 Errno::ENOENT 错误就将被产生。

*Errno 模块

Ruby 的异常对象是 exception 的子类。然而操作系统通常都是使用普通的整数来报告错误的。这个 Errno 模块就是用来动态的将这些操作系统错误映射到 Ruby 的类。因为这个子类是在这个 Errno 模块里面创建的,所以说它的名称应该是以 Errno:: 开头。这些 Errono:: 类的名字都是跟 Ruby 所处的环境有关。在一个典型的 UNIX 或者 Windows 平台上,有比如像 Errno::EACCES, Errno::EAGAIN, Errno::EINTR 等等。

如果要获取对应于一个特定错误的操作系统 error number 的话,就可以通过这个类的常数 Errno::error::Errno 来获得:

Errno::EACCES::Errno   #=> 13
Errno::EAGAIN::Errno   #=> 11
Errno::EINTR::Errno    #=> 4

image-20221003222805281

特定平台上操作系统错误的完整列表可以通过 Errno.constants得到:

Errno.constants

image-20221003222927120

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~