从可能未定义的错误中解救

时间:2016-04-11 20:10:06

标签: ruby error-handling

我的Rails网站(此问题纯粹基于Ruby)在测试/开发环境中使用AWS-SES(使用AWS的Action邮件程序)gem,我正在捕捉像这样的电子邮件传递可能出现的错误

def try_delivering_email(options = {})
    begin
      yield
      return false
    rescue  EOFError,
            ...
            AWS::SES::ResponseError,
            ... => e
      log_exception(e, options)
      return e
    end
end

现在问题是这个gem只针对特定环境定义,换句话说,AWS在开发中不存在,因此错误检查代码会因未定义的常量而抛出错误(haha)。

我已尝试将该行替换为(AWS::SES::ResponseError if defined?(AWS),但接下来的错误是

  

救援条款所需的类或模块

我怎样才能以最好的方式解决这个问题?

2 个答案:

答案 0 :(得分:4)

rescue-clause 的例外列表不一定是文字/静态列表:

excs = [EOFError]
defined?(AWS) && excs << AWS::SES::Response
# ...
rescue *excs => e

此处使用splat运算符*将数组转换为列表。

答案 1 :(得分:2)

你不能在rescue条款中包含条件,但是你可以盲目拯救,然后对使用传统Ruby代码处理它的方式挑剔:

rescue EOFError => e
  log_exception(e)

  e
rescue => e
  if (defined?(AWS) and e.is_a?(AWS::SES::Response))
    # ...
  else
    raise e
  end
end

这不是最好的方式,但它能完成这项工作。您总是可以将大量内容封装到一些模块中,以便更整齐地进行测试:

def loggable_exception?(e)
  case (e)
  when EOFError, AnotherError, EtcError
    true
  else
    if (defined?(AWS) and e.is_a?(AWS::SES::Response))
      true
    else
      false
    end
  end
end

然后你可以这样做,因为方法名称应该是不言自明的:

rescue => e
  if (loggable_exception?(e))
    log_exception(e)

    e
  else
    raise e
  end
end

如果log_exception返回给出的异常,你可以使它更整洁。不要忘记Ruby默认情况下&#34; return&#34;除非你提前做好,否则它不需要明确。