Rails 5 api 应用程序使用 json 错误响应而不是 html 错误响应

Rue*_*gen 5 ruby json ruby-on-rails http

如果我使用 --api 标志在 Rails 中创建应用程序,我的错误响应将采用 html 而不是 json 格式。

如何更改默认错误处理程序,以便每当控制器操作中抛出错误时,我都会收到包含错误和 http 状态的仅 json 响应?

现在我在每个自定义操作中使用下面的代码

rescue => e
    response.status = 422
    render json: { error: e.message }
Run Code Online (Sandbox Code Playgroud)

我宁愿不必每次都添加这个......

更新:我在应用程序控制器中使用了rescue_from方法

rescue_from Exception do |exception|
    render json: exception, status: 500
end
Run Code Online (Sandbox Code Playgroud)

但我觉得这是非常错误的,状态将始终被硬编码为 500

Vis*_*hal 6

您可以在路由中添加格式为 json,这样它将始终接受 json 格式的请求,如下所示

namespace :api, as: nil, defaults: { format: :json } do
     devise_for :users, controllers: {
        registrations: "api/v1/users/registrations",
        passwords: "api/v1/users/passwords"
      }

      resources :products, only: [:show,:index] do
        get "check_product_avaibility"
        get "filter", on: :collection
      end
end
Run Code Online (Sandbox Code Playgroud)

为了全局处理错误,您可以在应用程序控制器文件中添加 around_action

around_action :handle_exceptions, if: proc { request.path.include?('/api') }

# Catch exception and return JSON-formatted error
  def handle_exceptions
    begin
      yield
    rescue ActiveRecord::RecordNotFound => e
      @status = 404
      @message = 'Record not found'
    rescue ActiveRecord::RecordInvalid => e
      render_unprocessable_entity_response(e.record) && return
    rescue ArgumentError => e
      @status = 400
    rescue StandardError => e
      @status = 500
    end
    json_response({ success: false, message: @message || e.class.to_s, errors: [{ detail: e.message }] }, @status) unless e.class == NilClass
  end
Run Code Online (Sandbox Code Playgroud)

注意:render_unprocessable_entity_response 和 json_response 是自定义方法,您可以添加自己的方法来渲染 json 响应。