Ruby中的异常处理代码编写示例

单个异常使用 fail 关键字仅仅当捕获一个异常并且反复抛出这个异常(因为这里你不是失败,而是准确的并且故意抛出一个异常)。

  begin
   fail 'Oops'
  rescue => error
   raise if error.message != 'Oops'
  end

不要为 fail/raise 指定准确的 RuntimeError。

 # bad
  fail RuntimeError, 'message'

  # good - signals a RuntimeError by default
  fail 'message'

宁愿提供一个异常类和一条消息作为 fail/raise 的两个参数,而不是一个异常实例。

 # bad
  fail SomeException.new('message')
  # Note that there is no way to do `fail SomeException.new('message'), backtrace`.

  # good
  fail SomeException, 'message'
  # Consistent with `fail SomeException, 'message', backtrace`.

不要在 ensure 块中返回。如果你明确的从 ensure 块中的某个方法中返回,返回将会优于任何抛出的异常,并且尽管没有异常抛出也会返回。实际上异常将会静静的溜走。

 def foo
   begin
    fail
   ensure
    return 'very bad idea'
   end
  end

Use implicit begin blocks when possible.如果可能使用隐式 begin 代码块。

 # bad
  def foo
   begin
    # main logic goes here
   rescue
    # failure handling goes here
   end
  end

  # good
  def foo
   # main logic goes here
  rescue
   # failure handling goes here
  end

通过 contingency methods 偶然性方法。 (一个由 Avdi Grimm 创造的词) 来减少 begin 区块的使用。

  # bad
  begin
   something_that_might_fail
  rescue IOError
   # handle IOError
  end

  begin
   something_else_that_might_fail
  rescue IOError
   # handle IOError
  end

  # good
  def with_io_error_handling
    yield
  rescue IOError
   # handle IOError
  end

  with_io_error_handling { something_that_might_fail }

  with_io_error_handling { something_else_that_might_fail }

不要抑制异常输出。

  # bad
  begin
   # an exception occurs here
  rescue SomeError
   # the rescue clause does absolutely nothing
  end

  # bad
  do_something rescue nil

避免使用 rescue 的修饰符形式。

 # bad - this catches exceptions of StandardError class and its descendant classes
  read_file rescue handle_error($!)

  # good - this catches only the exceptions of Errno::ENOENT class and its descendant classes
  def foo
   read_file
  rescue Errno::ENOENT => ex
   handle_error(ex)
  end

不要用异常来控制流。

 # bad
  begin
   n / d
  rescue ZeroDivisionError
   puts "Cannot divide by 0!"
  end

  # good
  if d.zero?
   puts "Cannot divide by 0!"
  else
   n / d
  end

应该总是避免拦截(最顶级的) Exception 异常类。这里(ruby自身)将会捕获信号并且调用 exit,需要你使用 kill -9 杀掉进程。

  # bad
  begin
   # calls to exit and kill signals will be caught (except kill -9)
   exit
  rescue Exception
   puts "you didn't really want to exit, right?"
   # exception handling
  end

  # good
  begin
   # a blind rescue rescues from StandardError, not Exception as many
   # programmers assume.
  rescue => e
   # exception handling
  end

  # also good
  begin
   # an exception occurs here

  rescue StandardError => e
   # exception handling
  end

将更具体的异常放在救援(rescue)链的上方,否则他们将不会被救援。

  # bad
  begin
   # some code
  rescue Exception => e
   # some handling
  rescue StandardError => e
   # some handling
  end

  # good
  begin
   # some code
  rescue StandardError => e
   # some handling
  rescue Exception => e
   # some handling
  end

在 ensure 区块中释放你程式获得的外部资源。

 f = File.open('testfile')
  begin
   # .. process
  rescue
   # .. handle error
  ensure
   f.close unless f.nil?
  end

除非必要, 尽可能使用 Ruby 标准库中异常类,而不是引入一个新的异常类。(而不是派生自己的异常类)

(0)

相关推荐

  • 详解Ruby中的异常

    异常和执行总是被联系在一起.如果您打开一个不存在的文件,且没有恰当地处理这种情况,那么您的程序则被认为是低质量的. 如果异常发生,则程序停止.异常用于处理各种类型的错误,这些错误可能在程序执行期间发生,所以要采取适当的行动,而不至于让程序完全停止. Ruby 提供了一个完美的处理异常的机制.我们可以在 begin/end 块中附上可能抛出异常的代码,并使用 rescue 子句告诉 Ruby 完美要处理的异常类型. 语法 begin # - rescue OneTypeOfException #

  • ruby 异常处理:ensure

    当一个方法结束工作时我们也许需要进行清理工作.也许一个打开的文件需要关闭,缓冲区的数据应清空等等.如果对于每一个方法这里永远只有一个退出点,我们可以心安理得地将我们的清理代码放在一个地方并知道它会被执行;但一个方法可能从多个地方返回,或者因为异常我们的清理代码被意外跳过. begin   file = open("/tmp/some_file", "w")   # ... write to the file ...   file.close end 上面,如果在我们

  • ruby 异常处理:rescue

    一个运行着的程序常会遇到意外的问题.一个要读取的文件不存在;当希望存入一些数据时磁盘满了;用户可能输入不恰当的数据. ruby> file = open("some_file") ERR: (eval):1:in `open': No such file or directory - some_file 一个健壮的程序会合理并漂亮的处理这些问题.面对那些异常是一件讨人厌的工作.C程序员被要求做到检查每一个可能导致错误发生的系统调用的返回值并立刻做出决定. FILE *file =

  • Ruby中的异常处理代码编写示例

    单个异常使用 fail 关键字仅仅当捕获一个异常并且反复抛出这个异常(因为这里你不是失败,而是准确的并且故意抛出一个异常). begin fail 'Oops' rescue => error raise if error.message != 'Oops' end 不要为 fail/raise 指定准确的 RuntimeError. # bad fail RuntimeError, 'message' # good - signals a RuntimeError by default fai

  • Ruby中的block代码块学习教程

    1.什么是代码块 在Ruby中,{}或do...end之间的代码是一个代码块.代码块只能出现在一个方法的后边,它紧接在方法最后一个参数的同一行上,由yield关键字调用.例如: [1,2,3,4,5].each { |i| puts i } [1,2,3,4,5].each do |i| puts i end 块变量:以yield关键字调用block也可以传递参数,block中竖线(|)之间给出的参数名用于接收来自yield的参数. 竖线之间(如上例中的 | i |)的变量被称作块变量,作用和一

  • Python程序中的观察者模式结构编写示例

    察者模式定义 定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新.观察者模式提供了一种对象设计,让主题和观察者之间松耦合. 设计原则 为了交互对象之间的松耦合设计而努力.松耦合的设计之所以能让我们建立有弹性的系统,能够应对变化,是因为对象之间的互相依赖降到了最低. 模式结构与说明 1.Subject:主题(目标)接口,主题可以注册.移除对其感兴趣的观察者,在自身数据发生变化的时候,还可以通知这些观察者.一个主题可以有多个观察者,需要注意的是,观察者的顺

  • 在HTML中插入JavaScript代码的示例

    在HTML文档中的任何地方可包括JavaScript代码.但也有以下的最佳方法来包含JavaScript在HTML文件. 在 <head>...</head> 部分. 在 <body>...</body> 部分. 在<body>...</body> 和<head>...</head> 部分. 脚本和外部文件,然后包括在<head>... </ head>部分. 在下面的章节中,我们将看到

  • flask中主动抛出异常及统一异常处理代码示例

    本文主要介绍的是flask中主动抛出异常及统一异常处理的相关内容,具体如下. 在开发时,后台出现异常 ,但不想把异常显示给用户或者要统一处理异常时,可以使用abort主动抛出异常,再捕获异常返回美化后的页面. 主动抛出异常: @user.route('/testError') def testError(): print ('testError') abort(404) 使用装饰器errorhandler捕获异常: @user.errorhandler(404) def error(e): re

  • 利用RJB在Ruby on Rails中使用Java代码的教程

    开始之前 关于本教程 Ruby on Rails (Rails) 是用 Ruby 编写的一个 full-stack Web 应用程序框架,而 Ruby 是一种功能丰富的.免费的.可扩展的.可移植的.面向对象的脚本编制语言.Rails 在 Web 应用程序开发人员之间非常流行.通过它,可以快速有效地开发 Web 应用程序,并将其部署到任何 Web 容器中,例如 IBM? WebSphere? 或 Apache Tomcat. 在 Rails 和类似的 Web 应用程序开发框架出现之前,用于 Web

  • Spring中统一异常处理示例详解

    前言 系统很多地方都会抛出异常, 而Java的异常体系目标就是与逻辑解耦,Spring提供了统一的异常处理注解,用户只需要在错误的时候提示信息即可 在具体的SSM项目开发中,由于Controller层为处于请求处理的最顶层,再往上就是框架代码的. 因此,肯定需要在Controller捕获所有异常,并且做适当处理,返回给前端一个友好的错误码. 不过,Controller一多,我们发现每个Controller里都有大量重复的.冗余的异常处理代码,很是啰嗦. 能否将这些重复的部分抽取出来,这样保证Co

  • C++中try throw catch异常处理的用法示例

    前言 今天在开发过程中调用一个库函数结果库函数有throw操作,当前代码没有对throw进行捕获操作,导致进程在main 函数中捕获到异常导致进程crash.所以借此记录下c++关于try,throw,catch的用法. 程序运行时常会碰到一些异常情况,例如: 做除法的时候除数为 0: 用户输入年龄时输入了一个负数: 用 new 运算符动态分配空间时,空间不够导致无法分配: 访问数组元素时,下标越界:打开文件读取时,文件不存在. 这些异常情况,如果不能发现并加以处理,很可能会导致程序崩溃. 所谓

  • 详解Ruby中的代码块及其参数传递

    一,块的声明    块的声明在函数调用之后,用{..}括起来,或do..end封装.{}一般用在单行语句上,do..end用在多行语句上. (1..4).each{|v| print "#{v} "} #输出1 2 3 4 块可以带参数,与函数参数不同,块参数用||封装,当然,可以带多个参数.这些参数怎么定义,实际上是在函数内部定义好的,后面会讲到. 二,块内变量的访问    块内可以访问块外的变量,也就是块外的变量在块内是可见的,如 sum = 0 (1..5).each do |v

  • spring中的FactoryBean代码示例

    上篇文章中我们介绍了浅谈Spring的两种配置容器,接下来我们就了解下spring中的FactoryBean的相关内容,具体如下. 从SessionFactory说起: 在使用SSH集成开发的时候,我们有时候会在applicationContext.xml中配置Hibernate的信息,下面是配置SessionFactory的一段示例代码: <bean id="sessionFactory" class="org.springframework.orm.hibernat

随机推荐