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

Rails: Middleware injection causes "can't modify frozen Array" error in test environment #403

Closed
sriedel opened this issue Dec 5, 2017 · 10 comments
Labels
scheduled Work is starting on this feature/bug

Comments

@sriedel
Copy link

sriedel commented Dec 5, 2017

I have a rails environment with a pretty standard bugsnag initializer:

 Bugsnag.configure do |config|
   config.api_key = "my_api_key_here"
   config.notify_release_stages = ['production', 'staging'] 
 end

As a testing environment I'm using rspec 3.6.

When an error causes rspec to abort during parse-time, I get a plethora of "can't modify frozen Array" errors, obscuring the actual error causing the abort.

Adding a breakpoint to actionpack-5.0.6/lib/action_dispatch/middleware/stack.rb:96 (where the exception is ultimately thrown), I can see the following behavior:

  • Rails loads its environment
  • Middlewares are loaded
  • the ruby interpreter tries to parse the test in question and fails, raising an exception
  • Bugsnag tries to inject the Bugsnag::Rack middleware, causing the frozen Array error, since the middlewares array has been frozen after the Rails environment was done initializing
  • The frozen array exception is printed to the console once spec file that was to be loaded

The obvious way to allevate the issue would be to disable the loading of the bugsnag middleware entirely when testing, or load the middlewares required during Rails' initialization. However I haven't found anything in the documentation of bugsnag how this could be accomplished.

I've tried adding config.middleware.disable( Bugsnag::Rack ) to the initializer, however this doesn't prevent the injection of the Bugsnag::Rack middleware.

Is there a way, other than to exclude bugsnag from the test group in bundler and wrap the initializer in a conditional checking the rails environment?

This is using bugsnag-ruby 5.4.1 (I know, not the most current version...)

Thanks!

@Cawllec
Copy link
Contributor

Cawllec commented Dec 5, 2017

Hi @sriedel, at the moment we don't have a way of disabling specific middlewares during bugsnag initialisation. I suspect your suggestion of excluding bugsnag from the test group would be the most effective way of stopping this behaviour, but I'll have a look at how you can stop the rack middleware loading and get back to you.

@kattrali
Copy link
Contributor

kattrali commented Dec 7, 2017

This will likely have the same solution as #391 (set an environment variable to prevent Bugsnag middleware from loading), though the intended release is a part of the 6.x series. I'll look into whether it would be simple to backport to 5.x as well.

@kattrali kattrali added the scheduled Work is starting on this feature/bug label Dec 7, 2017
@sriedel
Copy link
Author

sriedel commented Dec 7, 2017

Thanks for getting back on this, @kattrali. I've managed to upgrade to 6.1.1 in the meantime, and am using the Gemfile groups/intitializer workaround for now. So no need to backport on my account :)

@cookrn
Copy link

cookrn commented Dec 14, 2017

We've also been seeing this in our application, particularly in CI for whatever reason. Previously though our test environment had the application level eager_load option set to true for no particular reason so we're currently investigating whether setting this back to false (as is the Rails default for new applications) fixes the issue. What is the eager_load setting in your app @sriedel? Does changing it affect this issue?

@sriedel
Copy link
Author

sriedel commented Dec 15, 2017

@cookrn we're using eager_load set to true as well - unfortunately this is an ancient code base that has been through tons of rails updates and currently depends on the eager loading mechanism to work properly.

Anyhow, with regards to this issue: yes, setting eager_loading to false does indeed show the real cause of the error and no frozen Array errors show up.

@Cawllec
Copy link
Contributor

Cawllec commented Dec 15, 2017

I'm out of office at the moment, but I'll take a look at the eager_load process and see if we can make the plugin work any better with it

@Cawllec
Copy link
Contributor

Cawllec commented Jan 22, 2018

Hi @sriedel, I'm having trouble replicating the frozen array error. Is there any more information you can give me about your RSpec setup?

@sriedel
Copy link
Author

sriedel commented Jan 26, 2018

Sorry for the late reply.

There's nothing terribly unusual about the setup. It's more or less the standard rails rspec setup you'd be using a few years ago (rspec-rails, capybara, capybara-webkit, database-cleaner, simplecov, webmock)

The only thing I can think of: We weren't using spring at the time the issue popped up. Maybe it's that - or a feature spec is needed with capybara to trigger this behaviour.

@Cawllec
Copy link
Contributor

Cawllec commented Jan 26, 2018

Well I've created a PR that adds an environment variable to disable Bugsnag auto-configuration, including the railtie. I'd suggest trying that out and seeing if it makes any difference. I'll still be looking into how we can solve this without having to disable the auto-setup.

@Cawllec
Copy link
Contributor

Cawllec commented Oct 10, 2018

Hi @sriedel, the change allowing control over how and when middleware is loaded has been released in version 6.7.0. The documentation for the change can be found here. If there are any ongoing issues related to this, would you mind creating a new issue for it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scheduled Work is starting on this feature/bug
Projects
None yet
Development

No branches or pull requests

4 participants