【问题标题】:Catching JSON request parse errors and return 500 Response in JSON - Rails捕获 JSON 请求解析错误并在 JSON 中返回 500 响应 - Rails
【发布时间】:2015-10-26 08:36:40
【问题描述】:

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

我试图删除在 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

应用程序.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

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

【问题讨论】:

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

标签: ruby-on-rails json


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    好的,我不确定发生了什么,但它现在可以正常工作,无需更改任何代码。如果我发现出了什么问题,我会再次更新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多