Edge Rails 的更新:Exception Handling 更新

Posted by yudi
on Saturday, January 05

根据不同的 application exception 提供不同的解决方式(比如 redirect user 或 render 特定的页面 )是很常见的设计模式。在这个 更新系列 之前我们经常需要在 controller 里超量加载 rescue_action_in_public method:

1
2
3
4
5
6
7
8
9
class PostsController < ApplicationController
  def rescue_action_in_public(exception)
    case(exception)
      when ActiveRecord::RecordNotFound then render :file => '/bad_record'
      when NoMethodError then render :file => '/no_method'
      else render :file => '/error'
    end
  end
end

很容易发现这段代码立即被扩展成了多组乱了套的 if/else 声明。

现在我们拥有了一套非常简洁的方法来通过新的 rescue_from 来铺展不同的 exception 与 handler 脉络。 rescue_from 使一个 exception 的类型与一个 handler 的方法名称直接栓到一起, 使得exception的处理变得更加简单易懂:

1
2
3
4
5
6
7
8
9
10
class PostsController < ApplicationController

  # 从 exception 到 handler methods 的声明
  rescue_from ActiveRecord::RecordNotFound, :with => :bad_record
  rescue_from NoMethodError, :with => :show_error

  def bad_record; render :file => '/bad_record'; end
  def show_error(exception); render :text => exception.message; end

end

请记住,exception handler methods 既可以作为无实参的 method, 也可以添加一个 问题形式的 exception 作为实参 (如上面的 show_error 所示)。

您也可以 使用 block 或者 proc 来设置 rescue_from 里的 exception处理方式:

1
2
3
4
5
6
7
class PostsController < ApplicationController

  # 从 exception 到 handler methods 的声明
  rescue_from(ActiveRecord::RecordNotFound) { |e| render :file => '/bad_record' }
  rescue_from NoMethodError, :with => proc { |e| render :text => e.message }

end

原文作者是 Ryan Daigle, 请访问他的博客
本片译文的原文地址:Track

Comments

Leave a response