在红宝石中,您可以重新获得多个刺激,如下所示:
begin
...
rescue Exception1, Exception2
...
rescue Exception1
...
rescue Exception2
...
end
但是我不知道如何引发多个异常:
1] pry(main)> ? raise
From: eval.c (C Method):
Owner: Kernel
Visibility: private
Signature: raise(*arg1)
Number of lines: 13
With no arguments, raises the exception in $! or raises
a RuntimeError if $! is nil.
With a single String argument, raises a
RuntimeError with the string as a message. Otherwise,
the first parameter should be the name of an Exception
class (or an object that returns an Exception object when sent
an exception message). The optional second parameter sets the
message associated with the exception, and the third parameter is an
array of callback information. Exceptions are caught by the
rescue clause of begin...end blocks.
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
或者我无法在加薪文档中找到答案
此操作的目的是我有一个API调用,此调用尝试在API中创建一个对象。 然后,APi可以从Activerecord验证程序返回对象中的所有问题,这样我就可以得出这样的想法:
422“项目不均匀”,“项目需要大于100” 422“项目不连” 200 OK“已创建项目” 500“我是发球区
这个想法是捕获并引发类似这样的异常
Begin
API CALL
rescue ItemnotEven,ItemnotBigger
do something
retry if
rescue ItemnotEven
retry if
rescue Connection error
Log cannot connect
end
答案 0 :(得分:5)
异常不应用于验证。基本上,您一般不应遍历堆栈进行验证。
您从根本上要做的是:
X是顶级的,可以处理所有内容。 X调用Y。Y调用Z。Z执行验证,然后执行某些操作,如果验证失败,则会引发异常。
您应该做的是:
X调用Y。Y调用V和X。V执行验证并根据事物是否有效返回结果。如果V表示无效,则Y不会呼叫X。 Y将无效或成功结果传播给X。X会执行if
/ else
的有效性,而不是rescue
。
但是可以说您确实想要这样做。您应该改用throw
/ catch
:
def validate_date(date)
errors = []
errors << 'Improper format' unless date.match?(/^\d{2}-\d{2}-\d{4}$/)
errors << 'Invalid day' unless date.match?(/^[0-3]\d/)
errors << 'Invalid month' unless date.match?(/-[12]\d-/)
errors << 'Invalid year' unless date.match?(/[12][90]\d{2}$/)
throw(:validation, errors) unless errors.empty?
end
def invoke_validation_and_do_stuff(date)
validate_date(date)
puts "I won't be called unless validation is successful for #{date}"
end
def meaningless_nesting(date)
invoke_validation_and_do_stuff(date)
end
def more_meaningless_nesting(date)
meaningless_nesting(date)
end
def top_level(date)
validation_errors = catch(:validation) do
more_meaningless_nesting(date)
nil
end
if validation_errors
puts validation_errors
else
puts 'Execution successful without errors'
end
end
top_level '20-10-2012'
# I won't be called unless validation is successful for 20-10-2012
# Execution successful without errors
top_level '55-50-2012'
# Invalid day
# Invalid month
答案 1 :(得分:1)
我不认为您可以引发多个异常,它会引发它发现的第一个异常,如果存在多个异常,或者取决于您引发的异常类型和救援类型,它将被最里面的救援语句捕获>
答案 2 :(得分:1)
用我所知道的任何语言,都没有这样的概念。 您可以连续引发一个异常,但不能一次引发多个异常,即使在多个线程上“同时”引发,它仍然是在不同控制流上引发的单个异常。
引发异常时,控制流转到该异常。您有两种选择:对此进行处理或崩溃。没有第三种选择,没有单独的控制流弹出并继续进行,直到相应地处理了此异常为止。
如果您希望看到注释中所述的多个失败,那么您仍然会一次执行一次,就像将其引发一样。引发异常,您可以检查,记录,执行任何操作,抑制异常,并查看是否发生异常。
如果您询问如何引发多个未处理的异常,那么这确实没有任何意义。类似于询问如何一次在两个地方。