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

Gracefully handle missing node #1105

Merged
merged 2 commits into from
Dec 15, 2017
Merged

Gracefully handle missing node #1105

merged 2 commits into from
Dec 15, 2017

Conversation

brasic
Copy link
Contributor

@brasic brasic commented Dec 14, 2017

The webpacker:check_node task blows up when node is not installed. The code that rescues Errno::ENOENT doesn't behave as expected when rails is loaded because ActiveSupport monkeypatches Kernel#` to suppress raising Errno::ENOENT. With this monkeypatch in place the code never reaches the fallback branch for legacy node versions introduced in #798.

We can fix this by manually raising the exception that the activesupport monkeypatch has suppressed.

Before:

$ bundle exec rake webpacker:check_node
[...]/gems/ruby-2.4.2/bin/rake: No such file or directory - node
rake aborted!
NoMethodError: undefined method `strip' for nil:NilClass
[...]/gems/webpacker-3.1.1/lib/tasks/webpacker/check_node.rake:16:in `block (2 levels) in <main>'

After:

$ bundle exec rake webpacker:check_node
[...]/gems/ruby-2.4.2/bin/rake: No such file or directory - node
[...]/gems/ruby-2.4.2/bin/rake: No such file or directory - nodejs
Node.js not installed. Please download and install Node.js https://nodejs.org/en/download/

Fixes #954

Running this task when rails is loaded doesn't behave as expected
because ActiveSupport monkeypatches Kernel#` as follows:
https://github.com/rails/rails/blob/7d75599c875b081f63fc292e454b25e8e42eb60e/activesupport/lib/active_support/core_ext/kernel/agnostics.rb
to suppress raising Errno::ENOENT.  With this monkeypatch in place the
code never reaches the fallback branch for legacy node versions
introduced in rails#798

We can fix this by manually raising the exception that the activesupport
monkeypatch has suppressed.
@@ -4,6 +4,7 @@ namespace :webpacker do
begin
begin
node_version = `node -v`
raise Errno::ENOENT if node_version.blank?
rescue Errno::ENOENT
node_version = `nodejs -v`
raise Errno::ENOENT if node_version.blank?
Copy link
Member

Choose a reason for hiding this comment

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

How about if we re-raise it outside of rescue then I guess we don't need to raise twice?

Copy link
Member

Choose a reason for hiding this comment

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

   begin
      node_version = `node -v`
   rescue Errno::ENOENT
      node_version = `nodejs -v`
    end

   raise Errno::ENOENT if node_version.blank?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gauravtiwari that approach would fix the "node not installed" issue but it would still leave the change in #798 nonfunctional since the first block would never raise so the nodejs branch would never be tried.

Copy link
Contributor Author

@brasic brasic Dec 14, 2017

Choose a reason for hiding this comment

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

Part of the issue is that I'm not sure we can depend one way or the other on whether or not the activesupport monkeypatch will be in place. This approach works whether Kernel#` is monkeypatched to suppress Errno::ENOENT or not, although I admit it's not very pretty.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This simplifies things a lot and works the same whether or not ActiveSupport has monkeypatched Kernel#`: e49d10a

Copy link
Member

Choose a reason for hiding this comment

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

Awesome 🍰 💯

Using shell syntax to choose either node or nodejs has the extra benefit
of never raising Errno::ENOENT whether or not Kernel#` has been
monkeypatched by ActiveSupport.
@brasic brasic changed the title Raise ENOENT like vanilla ruby when node is not installed Gracefully handle missing node Dec 15, 2017
@gauravtiwari gauravtiwari merged commit 4f5e1ac into rails:master Dec 15, 2017
@gauravtiwari
Copy link
Member

Thanks @brasic 👍 💯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

rake webpacker:check_node errors out if no node installed
2 participants