拯救PG::UndefinedTable而不是ActiveRecord::StatementInvalid

5
如果我试图删除一个不存在的表,例如,我会收到以下错误消息:
"#<ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation \"aiurea\" does not exist\n

我可以使用ActiveRecord::StatementInvalid来进行救援,但它对我来说太通用了;我想只在底层错误是PG::UndefinedTable时进行救援。我该怎么做?注意:error.cause可以导致基础错误,但我不确定这是否是“公共”接口,以及这是否是一种不显眼的方式来获得它。

1
cause方法作为API的一部分发布在http://ruby-doc.org/core-2.2.0/Exception.html#method-i-cause,因此我认为它是公共的...至少是尽可能公开的。 - Tim
但是我需要救援 ActiveRecord::StatementInvalid,并在内部设置条件来查找原因是否为 PG::UndefinedTable。这不是我可以直接在 rescue 中指定的东西吗? - linkyndy
3个回答

7

2018年更新:

ex.original_exception已被弃用,使用ex.cause代替。以下是我的解决方案:

rescue ActiveRecord::StatementInvalid => ex
  if ex.cause.is_a?(PG::UndefinedTable)
    # do something
  else
    raise ex
  end
end

2

ActiveRecord::StatementInvalid 是一个特殊的错误类型,它将其他错误封装在其中。您可以使用 .original_exception 访问原始错误:

rescue  ActiveRecord::StatementInvalid => ex
  ex.original_exception # this will return the `PG::UndefinedTable` class, which you can further inspect.
end

更好的做法是:
rescue ActiveRecord::StatementInvalid => ex
  if ex.original_exception.is_a?(PG::UndefinedTable)
    # do something
  else
    raise ex
  end
end

0

类似这样的代码应该可以运行

rescue  ActiveRecord::StatementInvalid => ex
  if ex.message =~ /PG::UndefinedTable/
    // Do stuff here
  else
    raise ex
  end
end

确实,但你必须承认它很丑。难道没有其他的方法吗? - linkyndy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接