如何在ruby中引发多个异常

如何在ruby中引发多个异常,ruby,validation,exception,exception-handling,Ruby,Validation,Exception,Exception Handling,在ruby中,您可以重新设置多个异常,如下所示: 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)

在ruby中,您可以重新设置多个异常,如下所示:

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确定“已创建项目” 500“我是一个发球壶

我们的想法是捕捉到这一点,并提出类似这样的异常

Begin
API CALL
rescue ItemnotEven,ItemnotBigger
do something 
retry if 
rescue ItemnotEven
retry if
rescue Connection error
Log cannot connect
end

我不认为您可以引发多个异常,它将引发它发现的第一个异常,如果存在多个异常,或者取决于您引发的异常类型和救援类型,它将被最内部的救援语句捕获。在我所知的任何语言中,都不存在这样的概念。 您可以连续引发单个异常,但不能一次引发多个异常,即使处理多个线程以“同时”引发,也仍然是在不同控制流上引发的单个异常

当引发异常时,控制流将转到该异常。您有两个选项:对其采取措施或崩溃。没有第三个选项,也没有单独的控制流弹出并继续,直到相应地处理该异常为止

如果您希望看到注释中所述的多个故障,那么您仍然会一次只看到一个,就像引发故障一样。引发异常时,您可以检查、记录、执行任何操作、抑制它,并查看下一个是否因其他原因引发异常


如果您询问如何引发多个未经处理的异常,那么这真的没有意义。这类似于询问如何同时在两个位置。

异常不应用于验证。一般来说,您不应遍历堆栈进行验证

从根本上说,您正在做的是:

X是顶级的,可以处理所有事情。X调用Y。Y调用Z。Z执行验证并在验证失败后执行某些操作,如果验证失败,则引发异常

你应该做的是:

X调用Y.Y调用V,X.V根据对象是否有效执行验证并返回结果。如果V说对象无效,Y不会调用X。Y将无效性或成功结果传播给X。X会按照
如果
/
否则
对有效性执行操作,而不是
救援


但是假设你真的想这么做。你应该使用
抛出
/
捕获

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
def验证日期(日期)
错误=[]

错误引发多个异常的目的是什么?甚至不清楚引发多个异常是什么意思。当你说你可以拯救多个异常时,这些异常不会同时被保存;你可以一次引发一个异常。目的是我可以得到一个对象构造的多个失败,所以我引发了一个异常对于每一个失败,引发多个异常甚至没有意义,我个人不知道有哪种语言可能会发生这样的事情。有这样的事情,比如内部异常,一个导致另一个,但没有引发它们……感谢您的澄清,但是如果我想在更正错误后重试,会发生什么errors@anquegi在<代码中>顶级
您可以查看
验证错误
是否包含您知道如何“修复”的错误。如果包含,请执行一些执行“修复”的操作。然后再次调用
顶级
(也称为递归)。感谢上次的澄清,这真是一个很好的解决方案answer@anquegi很高兴这有帮助。