fea*_*ool 33 json ruby-on-rails actioncontroller
我有一个"软件即服务"应用程序,它使用通过RESTful API传递的JSON.
简单地说:在使用带有JSON数据交换的RESTful API时,捕获和报告异常的最佳实践是什么?
我的第一个想法是通过生成脚手架来看看Rails的作用,但这显然是不对的.这是一段摘录:
class MumblesController < ApplicationController
# GET /mumbles/1
# GET /mumbles/1.json
def show
@mumble = Mumble.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @mumble }
end
end
end
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果JSON代码发送不存在的ID,例如
http://www.myhost.com/mumbles/99999.json
Run Code Online (Sandbox Code Playgroud)
那么Mumble.find()将引发ActiveRecord :: RecordNotFound.ActionController将捕获它并在HTML中呈现错误页面.但HTML对于期望JSON的客户端来说是无用的.
我可以通过将Mumble.find()包装在一个begin ... rescue RuntimeError块中并渲染JSON status =>:unprocessable_entity等来解决这个问题.
但是,如果客户端的应用程序发送无效路径,例如:
http://www.myhost.com/badtypo/1.json
Run Code Online (Sandbox Code Playgroud)
是一个基于JSON的应用程序应该捕获并返回JSON中的错误?如果是这样,我在哪里捕获它而不深入ActionDispatch?
总的来说,如果出现错误,我是否应该让ActionController生成HTML?那感觉不对......
fea*_*ool 75
(我在点击[发布你的问题]之前就找到了答案.但这也可以帮助其他人...)
rescue_from答案是使用ActionController rescue_from,如本指南中所述并在此处记录.特别是,您可以按以下行替换默认的404.html和500.html文件的默认呈现:
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
private
def record_not_found(error)
render :json => {:error => error.message}, :status => :not_found
end
end
Run Code Online (Sandbox Code Playgroud)
如果它对任何人有帮助,这就是我为纯粹的json api所做的一切:
在你的ApplicationController每个特定控制器继承,添加
# app/controllers/api/v1/application_controller.rb
# ...
rescue_from StandardError do |exception|
render json: { :error => exception.message }, :status => 500
end
# ...
Run Code Online (Sandbox Code Playgroud)
作为开发人员,您还希望查看痕迹(最好是有用的行,过滤掉宝石)。并使生产痕迹不可见:
rescue_from StandardError do |exception|
# Handle only JSON requests
raise unless request.format.json?
err = {error: exception.message}
err[:backtrace] = exception.backtrace.select do |line|
# filter out non-significant lines:
%w(/gems/ /rubygems/ /lib/ruby/).all? do |litter|
not line.include?(litter)
end
end if Rails.env.development? and exception.is_a? Exception
# duplicate exception output to console:
STDERR.puts ['ERROR:', err[:error], '']
.concat(err[:backtrace] || []).join "\n"
render :json => err, :status => 500
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15556 次 |
| 最近记录: |