【问题标题】:Ruby reraising exception w/ additional string argument带有/附加字符串参数的Ruby重新引发异常
【发布时间】:2011-11-07 05:37:43
【问题描述】:

情况是这样的。我希望 doStuff() 中的所有异常都通过代码冒泡,以便在更高级别处理它们。

我还想记录 any 异常在更高级别的 doStuff() 中发生的频率,目前正在这样做:

begin
  doStuff()
rescue Exception =>
  raise e, "specific error to log in a db"

doStuff 代码抛出了几十个异常,我想捕获这些事件中的每一个以放入数据库中。有一个doStuff2(),它也可以抛出相同的指令,我想知道它们来自哪个函数。

添加额外的字符串似乎改变了异常本身,并且我丢失了原始异常所具有的所有漂亮的格式和跟踪信息。

关于如何重新引发原始异常以及跟踪 doStuff() 中发生的所有异常的任何建议?

【问题讨论】:

    标签: ruby exception


    【解决方案1】:

    如果您在没有传递任何参数的情况下调用 raise,Ruby 将重新引发最后一个异常。

    begin
      doStuff()
    rescue => e
      log_exception(e)
      raise  # This will re-raise the last exception.
    end
    

    作为旁注,我想给你一些关于 Ruby 最佳实践的建议。

    1. doStuff() 方法不遵循 Ruby 命名约定。您应该在方法中使用下划线。请使用do_stuff。此外,如果没有参数,则无需使用()
    2. 永远不要拯救异常,而是拯救你需要拯救的最低级别的类。在大多数情况下,您可能想要挽救所有类型的 StandardError 或 RuntimeError。事实上,如果你在没有传递错误类型的情况下使用救援,Ruby 会自动救援任何 StandardError 的子类。 Exception 类是非常低级的,它也会捕获语法错误以及其他几个编译器问题。在这种情况下,您可能希望让应用程序崩溃,以免部署损坏的应用程序。

    【讨论】:

    • doStuff() 只是伪代码,抱歉。问题是我无法在此处记录异常。日志记录必须发生在更高级别。这个应用程序很“愚蠢”,对数据库或日志一无所知。我知道我不能同时引发 2 个异常,但这可以解决我的问题。其中一个会被捕获并记录下来,而另一个仍然会在代码中冒泡。
    【解决方案2】:

    你可以保存第一个异常的回溯和消息,并构造一个新的异常来引发

    begin
    rescue Exception => e 
      new_ex = Exception.new("Error while executing ...:#{e.message}")
      new_ex.set_backtrace(e.backtrace)
      raise new_ex
    end
    

    【讨论】:

      【解决方案3】:

      您不能立即引发新异常并保存先前的异常及其堆栈跟踪。不幸的是,Java 世界中的嵌套异常并不是开箱即用的。它将在 Ruby 2.1 中可用。这是一个相当热门的话题。 https://bugs.ruby-lang.org/issues/8257

      您仍然可以使用nesty gem 来拥有它。你只需要在你的异常类中include Nesty::NestedError。更多信息在这里:https://github.com/skorks/nesty/

      【讨论】:

        猜你喜欢
        • 2012-01-13
        • 1970-01-01
        • 1970-01-01
        • 2019-11-30
        • 2021-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多