在哪里以及如何处理Rails异常?

4
我目前参与开发一个大型Rails应用程序,通过自定义API gem与另一个产品进行接口交互。这导致了一种非常奇怪的错误处理方式。例如,当我们与其他产品进行交互时,它可能会返回身份验证错误,我们预料到这种情况。然后,我们在API gem中捕获该错误并抛出异常,该异常然后被捕获并在视图中传递给用户。
我不喜欢这种错误捕获方法,原因如下:
- 我们似乎不应该期望异常并在逻辑中使用它们。例如,有时我们想要覆盖对象 - 因此,我们捕获“对象已存在”的异常,然后继续保存我们的模型。 - 它需要很多特定的错误捕获。代码中有多个区域,我们需要使用if-else检查某些错误并相应地重定向。
话虽如此,我应该完善API gem,使其具有不抛出异常的简单功能吗?
if user.has_permission_in_product?
  if object.doesnt_exist_in_product?
    do something
  else
    redirect somewhere with errors
  end
else
  redirect somewhere else with errors
end

更可取的是
begin
  do something
rescue APIError => e
  if e.message =~ "no permission"
    redirect somewhere with errors
  elsif e.message =~ "already exists"
    redirect somewhere else with errors
  end
end

此外,如果首选第一种方法,那么我们如何处理在这些函数中可能抛出的实际API错误?将它们冒泡到控制器中的rescue_from中吗?
在模型中捕获并处理异常是否更好,还是在模型中抛出异常并在控制器中处理它们?
1个回答

12

您是否正在寻找rescue_from

在您的控制器中,请执行以下操作:

class MyController < ApplicationController
    rescue_from ActiveRecord::RecordNotFound, :with => :render_missing

    def render_missing
        render 'This is a 404', :status => 404
    end
end
每次触发 ActiveRecord::RecordNotFound 异常时,都会执行 render_missing 方法。您可以将其与任何异常类一起使用。您的控制器中不再需要任何 begin/rescue 代码块。当然,在模型中引发的任何异常也可以通过 rescue_from 捕获。

2
我知道rescue_from。对我来说,更相关的问题应该是:在控制应用程序时使用异常是不好的实践吗?如果是,为什么?我是否应该尽可能避免使用异常? - NolanDC
我认为你应该避免它们。 - Damien MATHIEU
2
有人会认为抛出异常可以使你的代码更易于管理。在底层抛出错误,然后在高层捕获它。只要确保正确清理事物即可。 - baash05

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