【发布时间】:2019-09-16 15:27:29
【问题描述】:
我有一个方法可以抛出带有一些有意义的描述的ParserException,并在任何StandardError 上抛出一般的ParserException:
作为一个最小的可重现示例:
begin
item = parseItem(json)
if !item.id
raise ParserException.new("id property is missing")
end
item
rescue => ex
raise ParserException.new("exception occurred when tried to parse JSON", ex: ex)
end
现在的问题是,如果id 属性丢失,那么ParserException 将被捕获,并包装到另一个ParserException 中,然后用意义不大的消息重新抛出。
我可以通过这样做来解决它:
begin
# ...
rescue ParserException
raise
rescue => ex
raise ParserException.new("exception occurred when tried to parse JSON", ex: ex)
end
但它可能看起来有点难看。有没有更简洁的方法来实现这一目标? rescue !ParserException => ex 之类的东西?
例如,在 C# 中我可以做到(这可能也被认为是丑陋的,但我是出于好奇而问的):
try
{
throw new ParserException("Specific error");
catch (Exception ex) when (!(ex is ParserException))
{
throw new ParserException("Generic error");
}
【问题讨论】:
-
您提出了可行的解决方案(特别是
rescue,然后是 sink-allrescue)是惯用的正确方法。无论如何,它并不丑。 -
如果
ParserException是你的类,你可以重新实现它的initialize函数并且如果ex是已经一个ParserException只是克隆它。然后单个rescue就可以了。 -
@AlekseiMatiushkin 谢谢你的回答 :) 是的,我最担心的是 Ruby 习语,因为我只是在学习这门语言。第二个想法听起来也不错,我会试试这个。
-
当你说异常是“捕获,包装,然后用意义不大的消息重新抛出”时,其他类型的异常不会发生这种情况吗?或者那是你真正想要的?
-
@arcadeblast77 哦,是的,这就是我希望对任何其他类型的任何意外异常发生的情况 :) 但我想让我的
ParserExceptions 通过原始消息传递