Ruby on rails 捕获JSON请求解析错误并在JSON-Rails中返回500个响应

Ruby on rails 捕获JSON请求解析错误并在JSON-Rails中返回500个响应,ruby-on-rails,json,Ruby On Rails,Json,我正在编写一个Rails API,希望捕获请求中的任何JSON解析错误,并返回一个格式良好的JSON,其中包含有用的信息。我尝试了以下解决方案,添加了一个类来捕获解析错误,引用 我试图删除在ACCEPT头中检查JSON格式的if语句,但仍然不起作用。我认为这个请求根本就没有触及这个中间件 任何帮助都将不胜感激。同样有用的是,我应该如何自己调试它。谢谢 # in app/middleware/catch_json_parse_errors.rb class CatchJsonParseErrors

我正在编写一个Rails API,希望捕获请求中的任何JSON解析错误,并返回一个格式良好的JSON,其中包含有用的信息。我尝试了以下解决方案,添加了一个类来捕获解析错误,引用

我试图删除在ACCEPT头中检查JSON格式的if语句,但仍然不起作用。我认为这个请求根本就没有触及这个中间件

任何帮助都将不胜感激。同样有用的是,我应该如何自己调试它。谢谢

# in app/middleware/catch_json_parse_errors.rb
class CatchJsonParseErrors
  def initialize(app)
    @app = app
  end

  def call(env)
    begin
      @app.call(env)
    rescue ActionDispatch::ParamsParser::ParseError => error
      if env['HTTP_ACCEPT'] =~ /application\/json/
        error_output = "There was a problem in the JSON you submitted: #{error}"
        return [
          400, { "Content-Type" => "application/json" },
          [ { status: 400, error: error_output }.to_json ]
        ]
      else
        raise error
      end
    end
  end
end
application.rb

require File.expand_path('../boot', __FILE__)

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module Yomiapp
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # Do not swallow errors in after_commit/after_rollback callbacks.
    config.active_record.raise_in_transactional_callbacks = true

    config.middleware.insert_before ActionDispatch::ParamsParser, "CatchJsonParseErrors"

    config.generators do |g|
      g.test_framework :rspec, fixture: true
      g.fixture_replacement :factory_girl, dir: 'spec/factories'
      g.view_specs false
      g.helper_specs false
      g.stylesheets = false
      g.javascripts = false
      g.helper = false
    end

    config.autoload_paths += %W(\#{config.root}/lib)

    config.middleware.insert_before 0, "Rack::Cors" do
      allow do
        origins '*'
        resource '*',
          headers: :any,
          methods: [:get, :post, :delete, :put, :patch, :options],
          max_age: 0
      end
    end

    config.middleware.use ActionDispatch::Flash
  end
end
需要文件。展开路径('../boot',文件)
需要“rails/all”
#需要Gemfile中列出的宝石,包括任何宝石
#您仅限于:测试、开发或:生产。
Bundler.require(*Rails.groups)
Yomiapp模块
类应用程序
rake中间件

use Rack::Cors
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x000001040ce608>
use Rack::Runtime
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use CatchJsonParseErrors
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Warden::Manager
use ActionDispatch::Flash
run Yomiapp::Application.routes
使用机架::Cors
使用ActionDispatch::Static
使用Rack::Lock
使用#
使用Rack::Runtime
使用ActionDispatch::RequestId
使用Rails::Rack::Logger
使用ActionDispatch::ShowExceptions
使用ActionDispatch::DebugExceptions
使用ActionDispatch::RemoteIp
使用ActionDispatch::Reloader
使用ActionDispatch::回调
使用ActiveRecord::Migration::CheckPending
使用ActiveRecord::ConnectionAdapters::ConnectionManagement
使用ActiveRecord::QueryCache
使用CatchJsonParseErrors
使用ActionDispatch::ParamSpaser
使用Rack::Head
使用Rack::ConditionalGet
使用Rack::ETag
使用管理员::管理员
使用ActionDispatch::Flash
运行Yomiapp::Application.routes

好的,我不确定发生了什么,但它现在工作,没有任何代码更改。如果我发现了什么地方出了问题,我会再次更新。

好的,我不确定发生了什么,但它现在工作了,没有任何代码更改。如果我发现问题所在,我将再次更新。

我认为您只需要重新启动服务器。application.rb中的更改仅在您重新启动服务器时生效。现在,您可以停止服务器运行rake中间件命令,并刷新application.rb并开始正常工作。

我认为您只需要重新启动服务器。application.rb中的更改仅在您重新启动服务器时生效。现在,您可以停止服务器运行rake middleware命令,并刷新application.rb并开始正常工作。

在控制台上运行“rake middleware”检查您的中间件是否正确插入,并在列表中找到“CatchJsonParseErrors”。@pardepsaini谢谢。我更新了上面的
rake中间件
结果。您可以看到CatchJsonParseErrors就在上面。请在控制台上使用ActionDispatch::ParamsParserrun“rake middleware”检查您的中间件是否正确插入,并在列表中找到“CatchJsonParseErrors”。@pardepsaini谢谢。我更新了上面的
rake中间件
结果。您可以看到CatchJsonParseErrors就在use ActionDispatch::ParamsParser的上方