Tag: Ruby 1.9.3

PhusionPassenger::UnknownError: Psych::SyntaxError – tab character that violate intendation

Yesterday I've started (after trying to restart Passenger) to see this exception coming out from Apache error.log:

[ pid=5098 thr=5896300 file=utils.rb:176 time=2012-08-31 19:00:45.293 ]:
*** Exception PhusionPassenger::UnknownError in 
PhusionPassenger::ClassicRails::ApplicationSpawner ((<unknown>): 
found a tab character that violate intendation while scanning a plain scalar at line 49 in 11
(Psych::SyntaxError)) (process 5098, thread #<Thread:0x00000000b3f0d8>):

Passenger ApplicationSpawner was endlessly creating new instances of my app, because the previous onces needed to be shutdown because of this error. It was quite obvious for me, that the error came from invalid yaml file (Psych::SyntaxError), however stack trace looked like this:

from /usr/local/lib/ruby/1.9.1/psych.rb:203:in `parse'
from /usr/local/lib/ruby/1.9.1/psych.rb:203:in `parse_stream'
from /usr/local/lib/ruby/1.9.1/psych.rb:151:in `parse'
from /usr/local/lib/ruby/1.9.1/psych.rb:127:in `load'
from /gems/settingslogic-2.0.8/lib/settingslogic.rb:114:in `initialize'
from /gems/settingslogic-2.0.8/lib/settingslogic.rb:71:in `new'
from /gems/settingslogic-2.0.8/lib/settingslogic.rb:71:in `instance'
from /gems/settingslogic-2.0.8/lib/settingslogic.rb:77:in `method_missing'
from /home/httpd/v5.senpuu.net/releases/20120829194758/config/initializers/resque.rb:5
from /gems/activesupport-3.2.8/lib/active_support/dependencies.rb:245:in `load'
from /gems/activesupport-3.2.8/lib/active_support/dependencies.rb:245:in `block in load'
from /gems/activesupport-3.2.8/lib/active_support/dependencies.rb:236:in `load_dependency'
from /gems/activesupport-3.2.8/lib/active_support/dependencies.rb:245:in `load'
from /gems/railties-3.2.8/lib/rails/engine.rb:588:in `block (2 levels) in <class:Engine>'
from /gems/railties-3.2.8/lib/rails/engine.rb:587:in `each'
from /gems/railties-3.2.8/lib/rails/engine.rb:587:in `block in <class:Engine>'
from /gems/railties-3.2.8/lib/rails/initializable.rb:30:in `instance_exec'
from /gems/railties-3.2.8/lib/rails/initializable.rb:30:in `run'
from /gems/railties-3.2.8/lib/rails/initializable.rb:55:in `block in run_initializers'
from /gems/railties-3.2.8/lib/rails/initializable.rb:54:in `each'
from /gems/railties-3.2.8/lib/rails/initializable.rb:54:in `run_initializers'
from /gems/railties-3.2.8/lib/rails/application.rb:136:in `initialize!'
from /gems/railties-3.2.8/lib/rails/railtie/configurable.rb:30:in `method_missing'

Ok, bot how to find the file with invalid yaml syntax? In my case, this exception was raised when SettingsLogic could not parse the given yaml file. So I've decided to hookup into it, just before the parsing, so I would be able to print out the invalid file. To do so I've edited /gems/settingslogic-2.0.8/lib/settingslogic.rb file. If you go to line 114 of this file, you will see something like this:

hash = YAML.load(ERB.new(File.read(hash_or_file)).result).to_hash
if self.class.namespace
  hash = hash[self.class.namespace] or return missing_key("Missing setting '#{self.class.namespace}' in #{hash_or_file}")
end

So in order to print the invalid file name we just need to add:

p hash_or_file

just before the YAML.load method execution. After this, it was really easy to find an invalid line in my yaml file.

Ruby 1.9.3, Gruff and ZeroDivisionError: divided by 0

After updating Ruby from 1.9.2 to 1.9.3, Gruff stopped working. When I was trying to generate charts, it would throw following exception:

ZeroDivisionError: divided by 0
./gems/gruff-0.3.6/lib/gruff/base.rb:1066:in `label'
./gems/gruff-0.3.6/lib/gruff/base.rb:590:in `setup_graph_measurements'
./gems/gruff-0.3.6/lib/gruff/base.rb:532:in `setup_drawing'
./gems/gruff-0.3.6/lib/gruff/base.rb:508:in `draw'
./gems/gruff-0.3.6/lib/gruff/line.rb:53:in `draw'
./gems/gruff-0.3.6/lib/gruff/base.rb:493:in `to_blob'

How to fix this?

If you look into Gruff source code, you will see, that the error occurs in label method:

def label(value)
  label = if ((@spread.to_f % @marker_count.to_f == 0) || 
    !@y_axis_increment.nil?)
    value.to_i.to_s
  elsif @spread > 10.0
    sprintf("%0i", value)
  elsif @spread >= 3.0
    sprintf("%0.2f", value)
  else
    value.to_s
  end

  parts = label.split('.')
  parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{THOUSAND_SEPARATOR}")
  parts.join('.')
end

As you can see (or not) it happens, that the @marker_count variable is equal 0. When it happens, we try to divide by zero and the ZeroDivisionError exception is raised. To prevent this from happening, we need to patch this method (until the proper fix is released). Lets overwrite this method:

module Gruff
  class Base
    def label(value)
      label = if @marker_count.to_f == 0
        value.to_i.to_s
      elsif ((@spread.to_f % @marker_count.to_f == 0) || 
        !@y_axis_increment.nil?)
        value.to_i.to_s
      elsif @spread > 10.0
        sprintf("%0i", value)
      elsif @spread >= 3.0
        sprintf("%0.2f", value)
      else
        value.to_s
      end

      parts = label.split('.')
      parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{THOUSAND_SEPARATOR}")
      parts.join('.')
    end
  end
end

Thats all. First we check if @marker_count is equal 0 and if so, we return the whole value casted to integer. The rest of method stays the same.

Copyright © 2025 Closer to Code

Theme by Anders NorenUp ↑