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

Distinguish missing controller exceptions from unrelated NameError #37834

Merged

Conversation

casperisfine
Copy link
Contributor

Fix: #37650

The classic autoloader used to totally unregister any constant that
failed midway. Which mean "SomeConst".constantize was idempotent.

However Zeitwerk rely on normal Kernel#require behavior, which mean
that if an exception is raised during a class/module definition,
it will be left incompletely defined. For instance:

class FooController
  ::DoesNotExist

  def index
  end
end

Will leave FooController defined, but without its index method.

Because of this, when silencing a NameError, it's important
to make sure the missing constant is really the one we were trying
to load.

This patch

I tried writing a test case for it in railties/test/application/middleware/exceptions_test.rb but without success. If you have an idea of a proper way to test this case, I'm all ears.

Also this patch won't fully work without fxn/zeitwerk#99, because Zeitwerk::NameError#name isn't set as of zeitwerk 2.2.1.

@rafaelfranca @fxn thoughts?

cc @etiennebarrie @Edouard-chin

@rails-bot rails-bot bot added the actionpack label Nov 29, 2019
@casperisfine casperisfine force-pushed the handle-unrelated-name-error-in-router branch from 3f9045e to 3cee27b Compare November 29, 2019 16:45
@@ -529,7 +529,7 @@ GEM
websocket-extensions (0.1.4)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.2.0)
zeitwerk (2.2.2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we change the minimum version in the gemspec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'll do it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@casperisfine casperisfine force-pushed the handle-unrelated-name-error-in-router branch from 3cee27b to 11f5fb8 Compare December 4, 2019 15:03
@casperisfine casperisfine force-pushed the handle-unrelated-name-error-in-router branch from 11f5fb8 to 6d0285a Compare December 4, 2019 15:11
Fix: rails#37650

The classic autoloader used to totally unregister any constant that
failed midway. Which mean `"SomeConst".constantize` was idempotent.

However Zeitwerk rely on normal `Kernel#require` behavior, which mean
that if an exception is raised during a class/module definition,
it will be left incompletely defined. For instance:

```ruby
class FooController
  ::DoesNotExist

  def index
  end
end
```

Will leave `FooController` defined, but without its `index` method.

Because of this, when silencing a NameError, it's important
to make sure the missing constant is really the one we were trying
to load.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

rescue_from doesn't throw an error when used with a non-existent or misspelled exception class
3 participants