Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArgumentError with regexp route with optional capture group #1332

Closed
dometto opened this issue Aug 14, 2017 · 4 comments · Fixed by #1333
Closed

ArgumentError with regexp route with optional capture group #1332

dometto opened this issue Aug 14, 2017 · 4 comments · Fixed by #1333
Milestone

Comments

@dometto
Copy link
Contributor

dometto commented Aug 14, 2017

I have the following route definition:

get %r{/pages(?:/(.+))?} do |path|
...
end

The regexp allows for an optional capture group. In sinatra v1.4, this would work as expected. At present, I am getting an ArgumentError: wrong number of arguments (given 0, expected 1). Backtrace:

 /gollum/lib/gollum/app.rb in block (2 levels) in <class:App>

          get %r{/pages(?:/(.+))?} do |path|

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in call

              proc { |a, p| unbound_method.bind(a).call(*p) } :

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in block in compile!

              proc { |a, p| unbound_method.bind(a).call(*p) } :

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in block (3 levels) in route!

                route_eval { block[*args] }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in route_eval

          throw :halt, yield

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in block (2 levels) in route!

                route_eval { block[*args] }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in block in process_route

            block ? block[self, values] : yield(self, values)

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in catch

          catch(:pass) do

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in process_route

          catch(:pass) do

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in block in route!

              returned_pass_block = process_route(pattern, conditions) do |*args|

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in each

            routes.each do |pattern, conditions, block|

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in route!

            routes.each do |pattern, conditions, block|

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in block in dispatch!

            route!

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in block in invoke

          res = catch(:halt) { yield }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in catch

          res = catch(:halt) { yield }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in invoke

          res = catch(:halt) { yield }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in dispatch!

          invoke do

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in block in call!

          invoke { dispatch! }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in block in invoke

          res = catch(:halt) { yield }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in catch

          res = catch(:halt) { yield }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in invoke

          res = catch(:halt) { yield }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in call!

          invoke { dispatch! }

.rvm/gems/ruby-2.4.1@gollum/gems/sinatra-2.0.0/lib/sinatra/base.rb in call

          dup.call!(env)

.rvm/gems/ruby-2.4.1@gollum/gems/rack-protection-2.0.0/lib/rack/protection/xss_header.rb in call

            status, headers, body = @app.call(env)
@namusyaka
Copy link
Member

I'm going to take a look at the issue in a few days.

@namusyaka
Copy link
Member

@dometto Ping? I've tried to reproduce your issue, but cannot be reproduced in my locally.

@hgregorian
Copy link

I've encountered a similar issue using Sinatra 1.4.8 using a regex route:

namespace %r{^/api(/v1)?$} do
  ...
  ...
  put '/user/:id/set_password' do |id| <<< Exception here
    ...
    ...
  end
end

Stacktrace:

ArgumentError: wrong number of arguments (given 2, expected 1)
	/opt/my_app/bin/app.rb:147:in `block (2 levels) in <top (required)>'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1610:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1610:in `block in compile!'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:975:in `block (3 levels) in route!'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:994:in `route_eval'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:975:in `block (2 levels) in route!'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1015:in `block in process_route'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1013:in `catch'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1013:in `process_route'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:973:in `block in route!'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:972:in `each'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:972:in `route!'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1085:in `block in dispatch!'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `block in invoke'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `catch'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `invoke'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1082:in `dispatch!'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:907:in `block in call!'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `block in invoke'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `catch'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `invoke'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:907:in `call!'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:895:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/logger.rb:15:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:212:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/head.rb:13:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/methodoverride.rb:22:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/show_exceptions.rb:25:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:182:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:2013:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `block in call'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1787:in `synchronize'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/urlmap.rb:66:in `block in call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/urlmap.rb:50:in `each'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/urlmap.rb:50:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/tempfile_reaper.rb:15:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/lint.rb:49:in `_call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/lint.rb:37:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/showexceptions.rb:24:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/commonlogger.rb:33:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:219:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/chunked.rb:54:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/rack-1.6.8/lib/rack/content_length.rb:15:in `call'
	/opt/my_app/gem/ruby/2.4.0/gems/unicorn-5.2.0/lib/unicorn/http_server.rb:562:in `process_client'
	/opt/my_app/gem/ruby/2.4.0/gems/unicorn-5.2.0/lib/unicorn/http_server.rb:658:in `worker_loop'
	/opt/my_app/gem/ruby/2.4.0/gems/unicorn-5.2.0/lib/unicorn/http_server.rb:508:in `spawn_missing_workers'
	/opt/my_app/gem/ruby/2.4.0/gems/unicorn-5.2.0/lib/unicorn/http_server.rb:132:in `start'
	/opt/my_app/gem/ruby/2.4.0/gems/unicorn-5.2.0/bin/unicorn:126:in `<top (required)>'
	/opt/my_app/gem/ruby/2.4.0/bin/unicorn:22:in `load'
	/opt/my_app/gem/ruby/2.4.0/bin/unicorn:22:in `<top (required)>'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/cli/exec.rb:74:in `load'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/cli/exec.rb:74:in `kernel_load'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/cli/exec.rb:27:in `run'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/cli.rb:332:in `exec'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/vendor/thor/lib/thor.rb:359:in `dispatch'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/cli.rb:20:in `dispatch'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/vendor/thor/lib/thor/base.rb:440:in `start'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/cli.rb:11:in `start'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/exe/bundle:34:in `block in <top (required)>'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/lib/bundler/friendly_errors.rb:100:in `with_friendly_errors'
	/opt/rh/rh-ruby24/root/usr/share/gems/gems/bundler-1.13.7/exe/bundle:26:in `<top (required)>'
	/opt/rh/rh-ruby24/root/usr/bin/bundle:22:in `load'
	/opt/rh/rh-ruby24/root/usr/bin/bundle:22:in `<main>'

@hgregorian
Copy link

Resolved my issue by ensuring that the route regex capture group is non-capturing:

Working:

%r{^/api(?:/v1)?$}

Non-working:

%r{^/api(/v1)?$}

@namusyaka namusyaka added this to the v2.0.1 milestone Feb 6, 2018
namusyaka added a commit that referenced this issue Feb 6, 2018
Add pattern matches to values for Mustermann::Concat. Fixes #1332
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants