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

coo*_*sse 4 ruby-on-rails

当仅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的“默认”错误格式。

sma*_*ton 5

在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
Run Code Online (Sandbox Code Playgroud)

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

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


coo*_*sse 3

您可以在 Rails 中配置 excepts_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
Run Code Online (Sandbox Code Playgroud)

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

 config.exceptions_app = ->(env) { ActionDispatch::PublicExceptionsPlus.new(Rails.public_path).call(env) }
Run Code Online (Sandbox Code Playgroud)

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