jeremyevans/roda

Plugins json_parser and params_capturing conflict

Closed this issue · 1 comments

Run this snippet with rackup:

require 'roda'

class App < Roda
  plugin :json_parser
  plugin :params_capturing

  route do |r|
    # GET / request
    r.root do
      puts request.POST
      ''
    end
  end
end

run App.freeze.app

Then curl http://localhost:9292 -H 'Content-Type: application/json' -d '{'; the body is a malformed JSON. This error is raised:

UncaughtThrowError: uncaught throw :halt
	<gems path>/roda-3.26.0/lib/roda.rb:722:in `throw'
	<gems path>/roda-3.26.0/lib/roda.rb:722:in `halt'
	<gems path>/roda-3.26.0/lib/roda/plugins/json_parser.rb:14:in `block in <module:JsonParser>'
	<gems path>/roda-3.26.0/lib/roda/plugins/json_parser.rb:61:in `rescue in POST'
	<gems path>/roda-3.26.0/lib/roda/plugins/json_parser.rb:58:in `POST'
	<gems path>/rack-2.0.7/lib/rack/request.rb:358:in `params'
	<gems path>/rack-2.0.7/lib/rack/request.rb:22:in `params'
	<gems path>/roda-3.26.0/lib/roda/plugins/params_capturing.rb:61:in `initialize'
	<gems path>/roda-3.26.0/lib/roda.rb:548:in `new'
	<gems path>/roda-3.26.0/lib/roda.rb:548:in `initialize'
	<gems path>/roda-3.26.0/lib/roda/plugins/direct_call.rb:18:in `new'
	<gems path>/roda-3.26.0/lib/roda/plugins/direct_call.rb:18:in `call'
	<gems path>/rack-2.0.7/lib/rack/tempfile_reaper.rb:15:in `call'
	<gems path>/rack-2.0.7/lib/rack/lint.rb:49:in `_call'
	<gems path>/rack-2.0.7/lib/rack/lint.rb:37:in `call'
	<gems path>/rack-2.0.7/lib/rack/show_exceptions.rb:23:in `call'
	<gems path>/rack-2.0.7/lib/rack/common_logger.rb:33:in `call'
	<gems path>/rack-2.0.7/lib/rack/chunked.rb:54:in `call'
	<gems path>/rack-2.0.7/lib/rack/content_length.rb:15:in `call'
	<gems path>/puma-3.12.1/lib/puma/configuration.rb:227:in `call'
	<gems path>/puma-3.12.1/lib/puma/server.rb:660:in `handle_request'
	<gems path>/puma-3.12.1/lib/puma/server.rb:474:in `process_client'
	<gems path>/puma-3.12.1/lib/puma/server.rb:334:in `block in run'
	<gems path>/puma-3.12.1/lib/puma/thread_pool.rb:135:in `block in spawn_thread'
::1 - - [12/Dec/2019:15:54:14 -0300] "GET / HTTP/1.1" 500 77914 0.0275

The error goes away if plugin :params_capturing is removed and is replaced by json_parser's default 400 response, as expected.

The error is not raised if the JSON is well-formed.

Thanks for the report and reproducible code. I agree that this is a bug. I'm testing a fix that will lazily initialize the 'captures' entry in params in params_capturing, which should fix the issue when using json_parser. It will also be faster when using params_capturing for routes where the params are not accessed.