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

NoMethodError: undefined method `each' for "[omitted]/app/stylesheets":String #1835

Closed
dnesting opened this issue Sep 16, 2015 · 3 comments
Closed
Labels
bug Something isn't working

Comments

@dnesting
Copy link

We are getting this error very rarely:

NoMethodError: undefined method `each' for "[omitted]/app/stylesheets":String
…uby/2.2.0/gems/sass-3.4.16/lib/sass/plugin/compiler.rb: 251:in `file_list'
…uby/2.2.0/gems/sass-3.4.16/lib/sass/plugin/compiler.rb: 205:in `update_stylesheets'
…/bundle/ruby/2.2.0/gems/sass-3.4.16/lib/sass/plugin.rb:  82:in `update_stylesheets'
…/bundle/ruby/2.2.0/gems/sass-3.4.16/lib/sass/plugin.rb:  54:in `check_for_updates'
…le/ruby/2.2.0/gems/sass-3.4.16/lib/sass/plugin/rack.rb:  51:in `call'
…ack-protection-1.5.3/lib/rack/protection/xss_header.rb:  18:in `call'
…rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:  18:in `call'
…gems/rack-protection-1.5.3/lib/rack/protection/base.rb:  49:in `call'
…gems/rack-protection-1.5.3/lib/rack/protection/base.rb:  49:in `call'
…-protection-1.5.3/lib/rack/protection/frame_options.rb:  31:in `call'
…dor/bundle/ruby/2.2.0/gems/rack-1.5.5/lib/rack/head.rb:  11:in `call'
…/ruby/2.2.0/gems/rack-1.5.5/lib/rack/methodoverride.rb:  21:in `call'
…ndle/ruby/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb:2021:in `call'
…ndle/ruby/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb:1486:in `block in call'
…ndle/ruby/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb:1795:in `synchronize'
…ndle/ruby/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb:1486:in `call'
….0/gems/padrino-core-0.12.5/lib/padrino-core/router.rb:  84:in `block in call'
….0/gems/padrino-core-0.12.5/lib/padrino-core/router.rb:  75:in `each'
….0/gems/padrino-core-0.12.5/lib/padrino-core/router.rb:  75:in `call'
…/ruby/2.2.0/gems/puma-2.13.4/lib/puma/configuration.rb:  78:in `call'
…/bundle/ruby/2.2.0/gems/puma-2.13.4/lib/puma/server.rb: 541:in `handle_request'
…/bundle/ruby/2.2.0/gems/puma-2.13.4/lib/puma/server.rb: 388:in `process_client'
…/bundle/ruby/2.2.0/gems/puma-2.13.4/lib/puma/server.rb: 270:in `block in run'
…le/ruby/2.2.0/gems/puma-2.13.4/lib/puma/thread_pool.rb: 106:in `call'
…le/ruby/2.2.0/gems/puma-2.13.4/lib/puma/thread_pool.rb: 106:in `block in spawn_thread'

It's possible the problem is a race condition when executing in a multi-threaded environment. In lib/sass/plugin/configuration.rb:

      def template_location_array
        old_template_location = options[:template_location]
        normalize_template_location!
        options[:template_location]
      ensure
        options[:template_location] = old_template_location
      end

Between execution of normalize_template_location! and the return of options[:template_location], another thread could have executed the same function and executed the 'ensure' block, restoring this value to its single-string form before this method returns.

If you're going to restore its value, consider refactoring normalize_template_location! into a function that simply returns an array, and use that here instead.

@dnesting
Copy link
Author

Another way this bug presents:

NoMethodError: undefined method `to_a' for "/home/vcap/app/app/stylesheets":String

….2.0/gems/sass-3.4.16/lib/sass/plugin/configuration.rb: 113:in `normalize_template_location!'
….2.0/gems/sass-3.4.16/lib/sass/plugin/configuration.rb:  92:in `template_location_array'
/home/vcap/app/vendor/bundle/ruby/2.2.0/gems/sass-3.4.16/lib/sass/plugin/compiler.rb: 251:in `file_list'
...

This shouldn't be possible unless options[:template_location] is getting modified concurrently.

@dnesting
Copy link
Author

Confirmed this was the problem with this test:

  def test_template_location_array_with_threads
    set_plugin_opts :template_location => template_loc
    threads = []
    1000.times do
      threads << Thread.new do
        1000.times do
          assert_equal [[template_loc, tempfile_loc]], Sass::Plugin.template_location_array
        end
      end
    end
    threads.each { |t| t.join }
  end

This fairly reliably fails with the existing code, and passes consistently with PR #1837.

@chriseppstein chriseppstein added the bug Something isn't working label Oct 7, 2015
@chriseppstein
Copy link

Patch looks good. we'll get it into the next release.

@nex3 nex3 closed this as completed in f27a670 Nov 13, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants