覆盖 Rails API 中错误的默认 json 格式



当 Rails API 中发生错误时,服务器会以 json 格式响应错误,格式如下:{"status":500,"error":"Internal Server Error"}

对于其他错误,格式也相同:{"status":404,"error":"Not Found"}

我想用以下格式呈现错误:{"errors": [{status: 404, title: "Not found"}]}.

基本上我想将所有错误的格式更改为相同,但我找不到这样做的方法。

我知道我可以使用(例如(rescue_from ActiveRecord::RecordNotFound, with: :my_method并覆盖单个异常,但这意味着当 Rails 已经在这样做时,我必须列出所有可能的异常并返回适当的代码。

我正在寻找的是一种可以覆盖的方法,并且我可以用来更改 Rails 的"默认"错误格式。

在 Rails 中执行此操作的最佳方法可能是定义一个exceptions_app(请参阅config.exceptions_app)哪个必须是自定义机架应用程序。这将允许您按照自己的选择呈现异常。可以在此处找到一个示例。

config.exceptions_app = ->(env) { ErrorsController.action(:show).call(env) }
class ErrorsController < ApplicationController
layout 'error'
def show
exception       = env['action_dispatch.exception']
status_code     = ActionDispatch::ExceptionWrapper.new(env, exception).status_code
# render whatever you want here
end
end

您还可以检查 rails 的默认实现是什么。

还有一种名为exception_handler的宝石可能是这里的替代品。 更多资源:https://devblast.com/b/jutsu-12-custom-error-pages-in-rails-4

您可以在Rails 中配置exceptions_app。

管理异常和呈现错误的默认中间件是ActionDispatch::PublicExceptions

第一件事是覆盖此中间件以实现我们的自定义行为。app/middlewares/action_dispatch文件夹中创建一个包含以下内容的public_exceptions_plus.rb文件:

module ActionDispatch
class PublicExceptionsPlus < PublicExceptions
def call(env)
request = ActionDispatch::Request.new(env)
status = request.path_info[1..-1].to_i
content_type = request.formats.first
# define here your custom format
body = { errors: [{ status: status,
title: Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500]) }] }
render(status, content_type, body)
end
end
end

之后,在config/application.rb中添加以下内容:

config.exceptions_app = ->(env) { ActionDispatch::PublicExceptionsPlus.new(Rails.public_path).call(env) }

感谢@smallbutton.com 的输入。我认为这是一个更好的解决方案,因为它不需要控制器,而只需要一个中间件。

最新更新