1

I'm attempting to send exceptions to a slack channel. This was my set up:

Added the following to my Gemfile

gem 'exception_notification'
gem 'slack-notifier'

Created a new initializer config/initializers/errors.rb

# Works in development with or without this require
require 'exception_notification'

Rails.application.config.middleware.use(
    ExceptionNotification::Rack,
    :slack => {
        :webhook_url => ENV["SLACK_ERROR_WEBHOOOK_URL"]
    }
)

I have rebuilt my docker images and deleted the gem cache volumes.

This works properly in my development environment (errors get sent to slack), but isn't working on my production server. The only real difference that I can think of between the two is the RAILS_ENV value, at least configuration-wise. I'm fairly new to Rails however, as well as deploying to a production environment.

Immediately upon starting the app (docker-compose up) it exits with the following error:

/usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:34:in `require': cannot load such file -- exception_notification (LoadError)
app_1           |   from /usr/local/bundle/gems/zeitwerk-2.3.0/lib/zeitwerk/kernel.rb:23:in `require'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `block in require'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:291:in `load_dependency'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `require'
app_1           |   from /app/config/initializers/errors.rb:1:in `<main>'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:319:in `block in load'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:291:in `load_dependency'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:319:in `load'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/engine.rb:667:in `block in load_config_initializer'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/notifications.rb:182:in `instrument'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/engine.rb:666:in `load_config_initializer'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/engine.rb:624:in `block (2 levels) in <class:Engine>'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/engine.rb:623:in `each'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/engine.rb:623:in `block in <class:Engine>'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/initializable.rb:32:in `instance_exec'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/initializable.rb:32:in `run'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/initializable.rb:61:in `block in run_initializers'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:422:in `block (2 levels) in each_strongly_connected_component_from'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:421:in `block in each_strongly_connected_component_from'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/initializable.rb:50:in `each'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/initializable.rb:50:in `tsort_each_child'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:415:in `call'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:415:in `each_strongly_connected_component_from'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:347:in `each'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:347:in `call'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'
app_1           |   from /usr/local/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/initializable.rb:60:in `run_initializers'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/application.rb:363:in `initialize!'
app_1           |   from /app/config/environment.rb:5:in `<main>'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
app_1           |   from /usr/local/bundle/gems/zeitwerk-2.3.0/lib/zeitwerk/kernel.rb:23:in `require'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `block in require'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:291:in `load_dependency'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `require'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:49:in `require_relative'
app_1           |   from config.ru:3:in `block in <main>'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/builder.rb:116:in `eval'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/builder.rb:116:in `new_from_string'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/builder.rb:105:in `load_file'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/builder.rb:66:in `parse_file'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/server.rb:349:in `build_app_and_options_from_config'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/server.rb:249:in `app'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/server.rb:422:in `wrapped_app'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/server.rb:312:in `block in start'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/server.rb:379:in `handle_profiling'
app_1           |   from /usr/local/bundle/gems/rack-2.2.2/lib/rack/server.rb:311:in `start'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/commands/server/server_command.rb:39:in `start'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/commands/server/server_command.rb:147:in `block in perform'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/commands/server/server_command.rb:138:in `tap'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/commands/server/server_command.rb:138:in `perform'
app_1           |   from /usr/local/bundle/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
app_1           |   from /usr/local/bundle/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
app_1           |   from /usr/local/bundle/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/command/base.rb:69:in `perform'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/command.rb:46:in `invoke'
app_1           |   from /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/commands.rb:18:in `<main>'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
app_1           |   from /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `block in require'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:291:in `load_dependency'
app_1           |   from /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `require'
app_1           |   from bin/rails:4:in `<main>'

I've verified that the gem exception_notification is indeed installed by running docker exec -it <container-name> gem list, which includes exception_notification (4.4.3) in the output, and also running docker exec -it <container-name> gem which exception_notification which gives /usr/local/bundle/gems/exception_notification-4.4.3/lib/exception_notification.rb

Running Ruby on Rails v6.0.2 and Ruby v2.6.3

Anand Bait
  • 331
  • 1
  • 12
e-e
  • 1,071
  • 1
  • 11
  • 20
  • Turn eager loading and class caching in development.rb and try running it locally -- odds are good you can replicate the error. – dbugger Aug 15 '20 at 18:41
  • I don't know the configs for those options, but I did just change the environment to `production` locally and it all still works – e-e Aug 15 '20 at 18:50
  • This error basically looks like due to `bootsnap`. Check https://github.com/Shopify/bootsnap/issues/253 this issue discussion or even there are other discussions where workarounds/solutions are provided. This might have happened due to caching done by Bootsnap – Anand Bait Aug 15 '20 at 18:53
  • @AnandBait I tried one of the suggestions, which was to comment out `require 'bootsnap/setup` in the `config/boot.rb` file in order to see if it was a bootsnap issue or if the stack trace was misleading, and now I'm seeing `/usr/local/bundle/gems/zeitwerk-2.3.0/lib/zeitwerk/kernel.rb:23:in `require': cannot load such file -- exception_notification (LoadError)` – e-e Aug 15 '20 at 19:05
  • As per official docs, I don't think `require 'exception_notification'` is needed. Secondly, please check if the gem included some non production group in gemfile? – Anand Bait Aug 15 '20 at 19:19
  • @AnandBait removing the require changes the error to `uninitialized constant ExceptionNotification (NameError)`. Also, the gem is not within a group in the gemfile. – e-e Aug 15 '20 at 19:22
  • And where is it saying as uninitialized? which line? what is the code there? is that at `ExceptionNotification::Rack` in errors.rb or somewhere else? – Anand Bait Aug 15 '20 at 19:38
  • @AnandBait yes, it is in the `config/initializers/errors.rb` file outlined in the original post. I have since removed the `require`, and so now is giving me the "uninitialized contant" error – e-e Aug 15 '20 at 19:55

2 Answers2

2

I had some similar problems when using Rails and Docker. Bootsnap cache may be stale.

Try removing the cache

rm tmp/cache/bootsnap-load-path-cache

You might also try restarting Spring

spring stop

It should restart automatically.

Kaom Te
  • 774
  • 1
  • 8
  • 17
  • No luck with removing the cache, and i'm not using spring. But thank you, I appreciate the suggestion. – e-e Aug 15 '20 at 18:59
  • Whats the output when you do a `docker-compose exec gem which exception_notification` ? – Kaom Te Aug 15 '20 at 19:12
  • I can't use `docker-compose exec ...` because the service in question fails immediately, but for some reason I _can_ get it running using `docker run `, which gives: `/usr/local/bundle/gems/exception_notification-4.4.3/lib/exception_notification.rb` – e-e Aug 15 '20 at 19:17
1

Try require 'exception_notification/rails'

Anand Bait
  • 331
  • 1
  • 12
  • `/usr/local/bundle/gems/zeitwerk-2.3.0/lib/zeitwerk/kernel.rb:23:in `require': cannot load such file -- exception_notification/rails` – e-e Aug 15 '20 at 20:11
  • This is weird. I found install generator at https://github.com/smartinez87/exception_notification/blob/master/lib/exception_notification.rb#L9 Run using `rails generate exception_notification:install` And then try adding your configurations to newly created file. So `require 'exception_notification/rails'` this was found from install generator only. – Anand Bait Aug 15 '20 at 20:22
  • Yeah I'm not really sure. I'm still confused why this is working fine in my development environment but not at all in production – e-e Aug 15 '20 at 20:39
  • One possible reason could be zeitwerk (framework used for loading) in new [Rails 6](https://edgeguides.rubyonrails.org/6_0_release_notes.html). Just to confirm, can you implement exception_notification in some old Rails project if you have? – Anand Bait Aug 16 '20 at 03:39