better_errors: NoMethodError at /__better_errors/xxxx/variables undefined method `id' for nil:NilClass
when I use better_errors work with Sinatra + Grape, it not works
my code is:
# configure.rb file
class Configure < Sinatra::Base
configure :development do
use BetterErrors::Middleware
BetterErrors.application_root = __dir__
end
end
# dashboard.rb file
class Dashboard < Sinatra::Base
use Configure
get('/') { raise }
end
# apiv1.rb file
class APIv1 < Grape::API
format :json
resource do
get :test do
raise
end
end
end
# config.ru file
require 'sinatra'
require 'grape'
require 'better_errors'
class Admin < Sinatra::Base
use Dashboard
end
class API < Grape::API
use BetterErrors::Middleware
mount APIv1 => '/api/v1'
end
run Rack::Cascade.new [API, Admin]
when i visit: http://0.0.0.0:9292/api/v1/test first APIv1 class raise an error, it works, the left is ok, but when i click a left section, the right deteils not work.
and then visit: http://0.0.0.0:9292 Dashboard class raise an error, it works, the left list and right details is ok.
it has an error, the details is:
NoMethodError at /__better_errors/0e1adbe07252ede1/variables
undefined method `id' for nil:NilClass
file: middleware.rb location: internal_call line: 127
and i view the code, and found:
def internal_call(env, opts)
if opts[:id] != @error_page.id
return [200, { "Content-Type" => "text/plain; charset=utf-8" }, [JSON.dump(error: "Session expired")]]
end
env["rack.input"].rewind
response = @error_page.send("do_#{opts[:method]}", JSON.parse(env["rack.input"].read))
[200, { "Content-Type" => "text/plain; charset=utf-8" }, [JSON.dump(response)]]
end
the @error_page is nil
and the second, when i first visit: http://0.0.0.0:9292 and then visit http://0.0.0.0:9292/api/v1/test
the error not occur any more, it just return an json: {“error”:“Session expired”}
please help
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 23 (1 by maintainers)
I’ve figured it out, at least for my case: a new
BetterErrors::Middleware
instance is being created for every request. This means@error_page
will benil
for any subsequentinternal_call
. The quick ‘n’ dirty solution is to instantiate a single instance and reuse it across all requests.Here’s how I did it:
Hope it helps!