简体   繁体   English

带有 json 错误响应而不是 html 错误响应的 rails 5 api 应用程序

[英]rails 5 api app with json error response instead of html error response

If I create an app in rails using the --api flag my error responses are in html rather than json.如果我使用 --api 标志在 rails 中创建一个应用程序,我的错误响应是 html 而不是 json。

How am I able to change the default error handler so that whenever an error is thrown in a controller action, I receive a json only response with the error and http status?如何更改默认错误处理程序,以便每当控制器操作中抛出错误时,我都会收到带有错误和 http 状态的仅 json 响应?

right now I am using the code below in every custom action现在我在每个自定义操作中使用下面的代码

rescue => e
    response.status = 422
    render json: { error: e.message }

I'd rather not have to add this each time...我宁愿不必每次都添加这个...

UPDATE: I used the rescue_from method in the application controller更新:我在应用程序控制器中使用了rescue_from 方法

rescue_from Exception do |exception|
    render json: exception, status: 500
end

But I feel this is very wrong and the status will always be hard coded as 500但我觉得这是非常错误的,状态总是硬编码为 500

you can add format as json in routes so it will always accept request in json format like below您可以在路由中添加格式为 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

For handling errors globally, you can add around_action in application controller file为了全局处理错误,您可以在应用程序控制器文件中添加 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

NOTE: render_unprocessable_entity_response and json_response are custom methods , you can add your own methods to render json response.注意:render_unprocessable_entity_response 和 json_response 是自定义方法,您可以添加自己的方法来呈现 json 响应。

You can use the api_error_handler gem .您可以使用api_error_handler gem

Include it in your bundler file:将其包含在您的打包程序文件中:

gem "api_error_handler", "~> 0.2.0"

The in your application controller, invoke the library.在您的应用程序控制器中,调用库。

class ApplicationController < ActionController::API
  handle_api_errors(
    # Error handling options go here if you want to override any defaults.
  )

  # ...
end

Now if you have a controller like this:现在,如果您有这样的控制器:


class UsersController < ApplicationController
  def index
    raise 'SOMETHING WENT WRONG!!!'
  end
end

When you hit this endpoint you will see this response当您点击此端点时,您将看到此响应

{
  "error": {
    "title": "Internal Server Error",
    "detail": "SOMETHING WENT WRONG!!!"
  }
}

And the status code will be set to an appropriate status code based on the type of error you had.并且状态代码将根据您遇到的错误类型设置为适当的状态代码。

See the gem's README for more info on how to configure the error response.有关如何配置错误响应的更多信息,请参阅 gem 的README

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM