Raise custom Exception with arguments
我在rails中的模型上定义了一个自定义异常,作为一种包装异常:(
当我提出异常时,我想传递一些关于a)内部函数引发错误的模型实例,以及b)捕获的错误的信息。
这是一个模型的自动导入方法,该方法由来自外部数据源的POST请求填充。
tldr; 如果您自己定义Exception,如何将参数传递给Exception? 我在该Exception上有一个initialize方法,但
使用new创建例外实例:
1 2 3 4 5 6 7 8 | class CustomException < StandardError def initialize(data) @data = data end end # => nil raise CustomException.new(bla:"blupp") # CustomException: CustomException |
解:
1 2 3 4 5 6 7 8 | class FooError < StandardError attr_reader :foo def initialize(foo) super @foo = foo end end |
如果您遵循Rubocop样式指南并始终将您的消息作为第二个参数传递给
1 | raise FooError.new('foo'), 'bar' |
你可以像这样得到
1 2 3 | rescue FooError => error error.foo # => 'foo' error.message # => 'bar' |
如果要自定义错误消息,请写入:
1 2 3 4 5 6 7 8 9 10 11 12 | class FooError < StandardError attr_reader :foo def initialize(foo) super @foo = foo end def message "The foo is: #{foo}" end end |
如果需要
说明:
将您的消息作为第二个参数传递给
正如Rubocop样式指南所说,消息和异常类应该作为单独的参数提供,因为如果你写:
1 | raise FooError.new('bar') |
并且想要将回溯传递给
1 | raise FooError.new('bar'), 'bar', other_error.backtrace |
正如这个答案所说,如果你想将异常重新引发为具有相同回溯和不同消息或数据的新实例,则需要传递回溯。
实施
问题的关键在于,如果
1 | raise FooError.new('foo'), 'bar', backtrace # case 1 |
和
1 | raise FooError, 'bar', backtrace # case 2 |
我们希望
在案例1中,由于您提供了错误实例而不是类,因此
在第2种情况下,
因此,在情况1中,
(a)接受传递给
(b)仅使用案例1或案例2样式与
(c)使
如果您不希望
如果使用case 2样式
如果您使用关键字参数(h / t Lemon Cat的答案),那么代码如下所示:
1 2 3 4 5 6 7 8 | class FooError < StandardError attr_reader :foo def initialize(message, foo: nil) super(message) @foo = foo end end |
提升看起来像:
1 2 | raise FooError, 'bar', backtrace raise FooError(foo: 'foo'), 'bar', backtrace |
以下是向错误添加代码的示例代码:
1 2 3 4 5 6 7 8 9 10 11 | class MyCustomError < StandardError attr_reader :code def initialize(code) @code = code end def to_s "[#{code}] #{super}" end end |
并提出它:
TL; DR在这个问题之后7年,我相信正确的答案是:
1 2 3 4 5 6 7 8 9 | class CustomException < StandardError attr_reader :extra def initialize(message=nil, extra: nil) super(message) @extra = extra end end # => nil raise CustomException.new('some message', extra:"blupp") |
警告:您将得到相同的结果:
1 | raise CustomException.new(extra: 'blupp'), 'some message' |
但那是因为
1 2 3 4 5 6 7 8 9 10 11 12 | static VALUE exc_exception(int argc, VALUE *argv, VALUE self) { VALUE exc; if (argc == 0) return self; if (argc == 1 && self == argv[0]) return self; exc = rb_obj_clone(self); exc_initialize(argc, argv, exc); return exc; } |
在
我的扩展舞蹈混音版本的原因是:https://stackoverflow.com/a/56371923/5299483
您可以创建
1 2 3 4 5 6 | begin # do something rescue => e error = MyException.new(e, 'some info') raise error end |