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

Doesn't work with spring #26

Open
TylerRick opened this issue May 21, 2019 · 0 comments · May be fixed by #27
Open

Doesn't work with spring #26

TylerRick opened this issue May 21, 2019 · 0 comments · May be fixed by #27

Comments

@TylerRick
Copy link
Contributor

Steps to reproduce

  1. Check out a Rails app that has spring inserted in the binstubs — for example, this example app:
    https://github.com/TylerRick/exception_notification-rake_example_with_spring/tree/workaround_using_load_in_bin_rake

  2. Run bin/rake check:exception

  3. Observe that no email is sent

How it's supposed to work

Normally (without spring), what happens is:

  • the bin/rake binstub gets loaded first, and
  • that is what triggers rake.rb and rake/rake_module.rb (which defines Rake.application) to get loaded.
  • Then Bundler.require loads exception_notification-rake gem, which checks that Rake.application is defined and patches Rake::Application#display_error_message

This is evident from the following backtraces taken at those 2 points:

"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/rake_module.rb:2:in `<top (required)>'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake.rb:44:in `require'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake.rb:44:in `<top (required)>'",
  require "rake/rake_module"
"bin/rake:8:in `require'",
"bin/rake:8:in `<main>'"]
  require 'rake'

(or if using global rake instead of bin/rake binstub:

"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/rake_module.rb:4:in `<top (required)>'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake.rb:44:in `<top (required)>'",
  require "rake/rake_module"
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/exe/rake:25:in `<top (required)>'",
"~/.gem/ruby/2.6.0/bin/rake:23:in `load'",
"~/.gem/ruby/2.6.0/bin/rake:23:in `<main>'"]
  load Gem.activate_bin_path('rake', 'rake', version)

)

"exception_notification-rake/lib/exception_notifier/rake/rake_patch.rb:5:in `<top (required)>'",
"exception_notification-rake/lib/exception_notifier/rake.rb:2:in `require'",
"exception_notification-rake/lib/exception_notifier/rake.rb:2:in `<top (required)>'",
"exception_notification-rake/lib/exception_notification/rake.rb:3:in `require'",
"exception_notification-rake/lib/exception_notification/rake.rb:3:in `<top (required)>'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:95:in `require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:95:in `rescue in block in require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:72:in `block in require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:65:in `each'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:65:in `require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler.rb:114:in `require'",
"example_app/config/application.rb:7:in `<top (required)>'",
  Bundler.require(*Rails.groups)
"example_app/Rakefile:4:in `require_relative'",
"example_app/Rakefile:4:in `<top (required)>'",
  require_relative 'config/application'
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/rake_module.rb:31:in `load'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/rake_module.rb:31:in `load_rakefile'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:703:in `raw_load_rakefile'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:104:in `block in load_rakefile'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:186:in `standard_exception_handling'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:103:in `load_rakefile'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:82:in `block in run'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:186:in `standard_exception_handling'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/application.rb:80:in `run'",
"bin/rake:10:in `<main>'"]

How it works instead when using spring

But when using spring:

  • spring's preload loads exception_notifier-rake gem before bin/rake is loaded
  • exception_notification-rake checks if Rake.application is defined; since it is not, it doesn't patch Rake::Application#display_error_message and so this gem has no effect
  • Then the bin/rake binstub gets loaded,
  • which triggers rake.rb and rake/rake_module.rb (which defines Rake.application) to get loaded (too late).

Again, you can see this from the backtraces if you wish:

"exception_notification-rake/lib/exception_notifier/rake/rake_patch.rb:5:in `<top (required)>'",
"exception_notification-rake/lib/exception_notifier/rake.rb:2:in `require'",
"exception_notification-rake/lib/exception_notifier/rake.rb:2:in `<top (required)>'",
"exception_notification-rake/lib/exception_notification/rake.rb:3:in `require'",
"exception_notification-rake/lib/exception_notification/rake.rb:3:in `<top (required)>'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:95:in `require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:95:in `rescue in block in require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:72:in `block in require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:65:in `each'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler/runtime.rb:65:in `require'",
"~/.rubies/ruby-2.6.0/lib/ruby/2.6.0/bundler.rb:114:in `require'",
"example_app/config/application.rb:7:in `<top (required)>'",
  Bundler.require(*Rails.groups)
"ruby/2.6.0/gems/spring-2.0.2/lib/spring/application.rb:92:in `require'",
"ruby/2.6.0/gems/spring-2.0.2/lib/spring/application.rb:92:in `preload'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake/rake_module.rb:2:in `<top (required)>'",
"~/.rubies/ruby-2.6.0/lib/ruby/gems/2.6.0/gems/rake-12.3.2/lib/rake.rb:44:in `<top (required)>'",
"example_app/bin/rake:8:in `<top (required)>'",
  require 'rake'
"~/.gem/ruby/2.6.0/gems/spring-2.0.2/lib/spring/command_wrapper.rb:40:in `call'",
"~/.gem/ruby/2.6.0/gems/spring-2.0.2/lib/spring/application.rb:201:in `block in serve'",

Workaround

One workaround is to add this line to bin/rake:

 require 'rake'
+load 'exception_notifier/rake/rake_patch.rb'
 Rake.application.run

But a better solution is needed that doesn't require modifying the binstubs that spring automatically generated...

TylerRick added a commit to TylerRick/exception_notification-rake that referenced this issue May 21, 2019
TylerRick added a commit to TylerRick/exception_notification-rake that referenced this issue May 22, 2019
TylerRick added a commit to TylerRick/exception_notification-rake that referenced this issue Jun 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant