Chr*_*ele 46 ruby exception-handling ruby-on-rails exception
我在rails中的模型上定义一个自定义Exception作为一种包装异常:( begin[code]rescue[raise custom exception]end)
当我提出异常时,我想传递一些关于a)内部函数引发错误的模型实例,以及b)捕获的错误的信息.
这是一个模型的自动导入方法,该方法由来自外部数据源的POST请求填充.
tldr; 如果您自己定义Exception,如何将参数传递给Exception?我在该Exception上有一个初始化方法,但raise语法似乎只接受一个Exception类和消息,没有传递给实例化过程的可选参数.
pho*_*oet 68
使用new创建例外实例:
class CustomException < StandardError
def initialize(data)
@data = data
end
end
# => nil
raise CustomException.new(bla: "blupp")
# CustomException: CustomException
Run Code Online (Sandbox Code Playgroud)
Max*_*ace 15
class FooError < StandardError
attr_reader :foo
def initialize(foo)
super
@foo = foo
end
end
Run Code Online (Sandbox Code Playgroud)
如果您遵循Rubocop样式指南并且始终将您的消息作为第二个参数传递给raise:这是最好的方法:
raise FooError.new('foo'), 'bar'
Run Code Online (Sandbox Code Playgroud)
你可以foo这样:
rescue FooError => error
error.foo # => 'foo'
error.message # => 'bar'
Run Code Online (Sandbox Code Playgroud)
如果要在其中定义错误消息,请foo写入:
class FooError < StandardError
attr_reader :foo
def initialize(foo)
super
@foo = foo
end
def message
"The foo is: #{foo}"
end
end
Run Code Online (Sandbox Code Playgroud)
foo正如Rubocop样式指南所说,消息和异常类应该作为单独的参数提供,因为如果你写:
raise FooError.new('bar')
Run Code Online (Sandbox Code Playgroud)
并且想要传递一个回溯raise,没有两次传递消息就没有办法做到这一点:
raise FooError.new('bar'), 'bar', other_error.backtrace
Run Code Online (Sandbox Code Playgroud)
正如这个答案所说,如果你想将异常重新引发为具有相同回溯和不同消息或数据的新实例,则需要传递回溯.
raise,打电话FooError,而不是foo以下是FooError使用Pry运行的测试代码实现的三种不同方法:
raise FooError.new('foo'), 'bar', backtrace # case 1
Run Code Online (Sandbox Code Playgroud)
在raise和'bar'消息未正确设置,raise正确的实现也是如此.
以下是向错误添加代码的示例代码:
class MyCustomError < StandardError
attr_reader :code
def initialize(code)
@code = code
end
def to_s
"[#{code}] #{super}"
end
end
Run Code Online (Sandbox Code Playgroud)
并提出它:
raise MyCustomError.new(code), message
TL;DR 这个问题 7 年后,我相信正确的答案是:
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")
Run Code Online (Sandbox Code Playgroud)
警告:您将获得相同的结果:
raise CustomException.new(extra: 'blupp'), 'some message'
Run Code Online (Sandbox Code Playgroud)
但那是因为Exception#exception(string)做了一个#rb_obj_cloneon self,然后调用exc_initialize(它不调用CustomException#initialize。来自error.c:
raise CustomException.new(extra: 'blupp'), 'some message'
Run Code Online (Sandbox Code Playgroud)
在后面的示例中#raise向上的上方,一个CustomException将被raise与D-message设置为“消息”和extra设置为“blupp”(因为它是一个克隆),但TWO CustomException第一条件:对象实际上创建CustomException.new通过,而第二#raise呼叫#exception的第一个实例CustomException创建了第二个克隆的CustomException.
我的扩展舞蹈混音版本为什么在:https : //stackoverflow.com/a/56371923/5299483