新手问题 关于 Rails 的异常处理

Talon · 发布于 2016年12月29日 · 最后由 Talon 回复于 2016年12月29日 · 387 次阅读
29173

最近在写rails项目的时候,对异常处理这一块有很多困惑,希望各位能帮我解惑,谢谢!下面是问题:

1.怎么处理在Controller里面抛出的异常?什么才是处理Controller异常的较好的实践?代码如下

class ProductsController < ApplicationController
  def show
    product_id = params[:product_id]
    #如果product_id为空,那么我们是不是应该主动抛出ActiveRecord::RecordNotFound异常,然后交给ApplicationController然后使用rescue_from进行处理?
    raise ActiveRecord::RecordNotFound unless product_id
    #还是应该像下面这样不主动检测product_id,让程序自己在查找对应的product时抛出异常?
    @product = Product.find(params[:product_id])

    #如果交由ApplicationControlller统一处理同类型的异常,那么就意味着所有抛出此类型异常的代码之后的行为都是相同的(如添加错误信息,跳转)
    #那么如果我有些可能抛出此类型异常的地方我不想跟其他地方一样抛出异常之后产生同样的行为,那么我应该怎么办?在Action中用begin-rescue-end块吗?这样会不会显得Action中的代码过于臃肿?
  end
end

2.我们应不应该在Model中的方法内抛出或者处理异常?

class Product < ApplicationRecord
  def title
    self.name + ' ' + product_properties.map(&:value).join(' ')
  end
  #像上面这段代码,如果product没有name这个字段也没有name这个方法,那么会抛出一个NoMethodError异常,我们应该怎样处理它?
  #产品发布到生产环境,怎么处理这些有可能在controller和model里面发生的异常才有更好的用户体验?
end
共收到 3 条回复
2
huacnlee · #1 · 2016年12月29日

问题 1:

Controller 里面,如果是调用 find 方法,你不需要额外处理 NotFound 的异常,因为 Rails 已经做了

def show
  @product = Product.find(params[:product_id])
end

上面这个例子,如果没找到,将会抛出 ActiveRecord::RecordNotFound,同时生产环境将会以 404 页面返回。

问题 2:

Model 里面是否要抛出异常,这个要看什么情况了,你要需要,也是可以那么做的(就好比 find 也是直接抛异常的),但总点是,Controller 里面要拦截处理,不要以 500 页面返回。

29173
Talon · #2 · 2016年12月29日

#1楼 @huacnlee 谢谢!我看之前的一个帖子里你说find方法抛出异常只有在Show这个Action里面不需要手动处理,生产环境会自动render 404,那Controller里面其他的Action呢?如果其他的Action需要手动捕获的话在ApplicationController里面rescue_from这种方式可好?如果在rescue_from里面指定了与render 404不同的行为,那么在Show Action中find方法抛出异常之后会怎样?render 404 or 自定义行为?

29173
Talon · #3 · 2016年12月29日

#1楼 @huacnlee 我去看一下Ruby-China的源码吧

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册