how to handle exceptions in JSON based RESTful code?
我有一个"软件即服务"应用程序,它使用通过RESTful API传递的JSON。
简单地说:在使用带有JSON数据交换的RESTful API时,捕获和报告异常的最佳实践是什么?
我的第一个想法是通过生成脚手架来看看Rails的作用,但这显然是不对的。这是一段摘录:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
在这种情况下,如果JSON代码发送不存在的ID,例如
1 | http://www.myhost.com/mumbles/99999.json |
那么Mumble.find()将引发ActiveRecord :: RecordNotFound。 ActionController将捕获它并在HTML中呈现错误页面。但HTML对于期望JSON的客户端来说是无用的。
我可以通过将Mumble.find()包装在
但是,如果客户端的应用程序发送无效路径,例如:
1 | http://www.myhost.com/badtypo/1.json |
是一个基于JSON的应用程序应该捕获并返回JSON中的错误?如果是这样,我在哪里捕获它而不深入ActionDispatch?
总的来说,如果出现错误,我是否应该让ActionController生成HTML?那感觉不对......
(我在点击[发布你的问题]之前就找到了答案。但这也可以帮助其他人...)
使用ActionController的
答案是使用ActionController的
1 2 3 4 5 6 7 8 | 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 |
如果它对任何人有帮助,这就是我为纯粹的json api所做的一切:
在每个特定控制器继承的
1 2 3 4 5 6 7 8 9 | # app/controllers/api/v1/application_controller.rb # ... rescue_from StandardError do |exception| render json: { :error => exception.message }, :status => 500 end # ... |
- 主要基于fearless_fool的回答
作为开发人员,您还需要查看跟踪(最好使用有用的行,过滤掉宝石)。并使生产中的痕迹不可见:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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" " render :json => err, :status => 500 end |
关于如何为编写JSON API代码保持一致的标准没有明确的共识,但这是我练习的一些内容(比你要求的更多):
在您的情况下,您可能会发现Rails respond_to和respond_with处理html / json /其他响应。即使在您的解决方案中,它仍然会有效地呈现HTML,但这不是您的客户端应用程序将解释的内容,而是会读取HTTP标头并获取HTTP响应代码,这就是触发"rescue_from"的内容。