2

I am currently migrating an app from Rails 4 to Rails 5.

I've encountered the following issue when trying to issue commands such as bundle exec rspec spec:

/Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:35:in `build': undefined method `new' for ActionDispatch::ParamsParser:Module (NoMethodError)
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `block in build'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `each'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `inject'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/actionpack-5.1.4/lib/action_dispatch/middleware/stack.rb:99:in `build'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:508:in `block in app'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:504:in `synchronize'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:504:in `app'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/application/finisher.rb:45:in `block in <module:Finisher>'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:30:in `instance_exec'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:30:in `run'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:59:in `block in run_initializers'
        from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:226:in `block in tsort_each'
        from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:348:in `block (2 levels) in each_strongly_connected_component'
        from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:429:in `each_strongly_connected_component_from'
        from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:347:in `block in each_strongly_connected_component'
        from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `each'
        from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `call'
        from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:345:in `each_strongly_connected_component'
        from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:224:in `tsort_each'
        from /Users/me/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/tsort.rb:203:in `tsort_each'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/initializable.rb:58:in `run_initializers'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/application.rb:353:in `initialize!'
        from /Users/me/Documents/mikamai/surveyeah/config/environment.rb:5:in `<top (required)>'
        from /Users/me/Documents/mikamai/surveyeah/spec/rails_helper.rb:4:in `require'
        from /Users/me/Documents/mikamai/surveyeah/spec/rails_helper.rb:4:in `<top (required)>'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `require'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `block in requires='
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `each'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration.rb:1455:in `requires='
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:112:in `block in process_options_into'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:111:in `each'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:111:in `process_options_into'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/configuration_options.rb:21:in `configure'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:99:in `setup'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:86:in `run'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:71:in `run'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/lib/rspec/core/runner.rb:45:in `invoke'
        from /Users/me/.rvm/gems/ruby-2.2.2/gems/rspec-core-3.7.0/exe/rspec:4:in `<top (required)>'
        from /Users/me/.rvm/gems/ruby-2.2.2/bin/rspec:23:in `load'
        from /Users/me/.rvm/gems/ruby-2.2.2/bin/rspec:23:in `<main>'
        from /Users/me/.rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `eval'
        from /Users/me/.rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `<main>'

I think the issue comes from the file application.rb which contains:

module MyApp
  class Application < Rails::Application

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

  end
end

I've tried to change that line to:

module MyApp
  class Application < Rails::Application

    config.middleware.use ActionDispatch::ParamsParser, 'CatchJsonParseErrors'

  end
end

but it hasn't fixed things. I took a look at the Rails 5 release notes and it seems that

ActionDispatch::ParamsParser is deprecated and was removed from the middleware stack. To configure the parameter parsers use ActionDispatch::Request.parameter_parsers=.

although I'm not sure how I'd use that.

The app/middleware/catch_json_parse_errors.rb file looks like this:

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

Anyone know how I'd update this middleware configuration for Rails 5? Any help much appreciated! :D thanks in advance

1 Answer 1

6

Fixed this with:

module MyApp
  class Application < Rails::Application

    require './lib/middleware/catch_json_parse_errors.rb'
    config.middleware.insert_before Rack::Head, CatchJsonParseErrors

  end
end

and my lib/middleware/catch_json_parse_errors.rb:

class CatchJsonParseErrors
  def initialize(app)
    @app = app
  end

  def call(env)
    begin
      @app.call(env)
    rescue ActionDispatch::Http::Parameters::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

notice how I also had to change from ActionDispatch::ParamsParser::ParseError to ActionDispatch::Http::Parameters::ParseError here. There's probably a nicer way to load middleware files in ./lib/middleware/ but this works for now.

Sign up to request clarification or add additional context in comments.

1 Comment

My code is similar but the middleware didn't rescue from ActionDispatch::Http::Parameters::ParseError even though I already insert before Rack::Head.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.