在这篇文章中,错误都是在api和基本控制器方法中避免的。但是,由于以下原因,处理错误可能不是最好的方法:
在ActionController::Base中,我们只在ApplicationController中处理ActiveRecord::RecordNotFound。但是对于ActionController::API,我必须拯救每个控制器中的ActiveRecord::RecordNotFound。那么,有什么最好的方法来处理这个问题吗?
为api使用Rails 5和“active_model_serializers”gem
ActionController::API
module Api
module V1
class UsersController < ActionController::API
before_action :find_user, only: :show
def find_user
@user = User.find(params[:id])
rescue ActiveRecord::RecordNotFound => e
render json: { error: e.to_s }, status: :not_found
end
end
end
end行动主计长:
class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
private
def record_not_found
render file: "#{Rails.root}/public/404", layout: true, status: :not_found
end
end发布于 2017-05-31 07:46:42
您可以在application_controller.rb中这样做
if Rails.env.production?
rescue_from ActiveRecord::RecordNotFound, with: :render_404
end
def render_404
render json: {meta: meta_response(404, "Record not found")}
end这将拯救所有的RecordNotFound异常与404,但仅在生产模式。
发布于 2018-11-30 23:45:09
ActionController::API包括ActionController::Rescue模块,它提供了rescue_from类方法。
我将创建一个Api::BaseController基类,Api::V1::UsersController可以使用它,而不是在每个控制器类上使用ActionController::API。这将允许您在一个地方拥有一个rescue_from,而不是在每个操作上都需要一个rescue块。
module Api
class BaseController < ActionController::API
rescue_from ActiveRecord::RecordNotFound, with: :handle_error
private
def handle_error(e)
render json: { error: e.to_s }, status: :bad_request
end
end
module V1
class UsersController < BaseController
def find_user
@user = User.find(params[:id])
end
end
end
end我还将进一步创建一个Api::V1::BaseController,以便更容易地对API进行版本控制。然后,如果您决定更改v2的错误格式,只需将Api::BaseController中的rescue_from移动到Api::V1::BaseController,并向新的Api::V2::BaseController添加一个新的rescue_from。
module Api
class CommonBaseController < ActionController::API
# code common across API versions
end
module V1
class BaseController < CommonBaseController
rescue_from ActiveRecord::RecordNotFound, with: :handle_error
private
def handle_error(e)
render json: { error: e.to_s }, status: :bad_request
end
end
end
module V2
class BaseController < CommonBaseController
# use a custom base error class to make catching errors easier and more standardized
rescue_from BaseError, with: :handle_error
rescue_from ActiveRecord::RecordNotFound, with: :handle_error
private
def handle_error(e)
status, status_code, code, title, detail =
if e.is_a?(ActiveRecord::RecordNotFound)
[:not_found, '404', '104', 'record not found', 'record not found']
else
[
e.respond_to?(:status) ? e.status : :bad_request,
e.respond_to?(:status_code) ? e.status_code.to_s : '400',
e.respond_to?(:code) ? e.code.to_s : '100',
e.respond_to?(:title) ? e.title : e.to_s,
e.respond_to?(:detail) ? e.detail : e.to_s
]
end
render(
json: {
status: status_code,
code: code,
title: title,
detail: detail
},
status: status
)
end
end
end
endhttps://stackoverflow.com/questions/44278052
复制相似问题