如何在ruby中引发多个异常

anq*_*egi 2 ruby validation exception-handling exception

在ruby中你可以重新启动,这样的多个例外:

begin
   ...
rescue Exception1, Exception2
  ...
rescue Exception1
  ...
rescue Exception2
  ...
end
Run Code Online (Sandbox Code Playgroud)

但我不知道如何提出多个例外:

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
Run Code Online (Sandbox Code Playgroud)

或者我无法在提高文档中看出这一点

这样做的一个原因是我有一个API调用,这个调用试图在API中创建一个对象.然后APi可以从Activerecord Validators返回对象中的所有问题,所以我可以像以下那样思考:

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
Run Code Online (Sandbox Code Playgroud)

ndn*_*kov 5

不应将例外用于验证.基本上,您不应该遍历堆栈以进行验证.

你从根本上做的是:

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

你应该做的是:

X调用Y.Y调用V和X.V执行验证并根据事物是否有效返回结果.如果V说事情无效,Y不会打电话给X. Ÿ传播无效性或成功的结果,以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
Run Code Online (Sandbox Code Playgroud)