martijn / xsv

High performance, lightweight .xlsx parser for Ruby that provides nothing a CSV parser wouldn't
https://storck.io/posts/announcing-xsv-1-0-0/
MIT License
194 stars 20 forks source link

1.0.2 NoMethodError: undefined method `scan' for nil:NilClass #29

Closed jdufresne closed 3 years ago

jdufresne commented 3 years ago

Staring with version 1.0.2 I'm seeing the following error:

     NoMethodError:
       undefined method `scan' for nil:NilClass
     # ./.bundle/ruby/2.7.0/gems/xsv-1.0.2/lib/xsv/helpers.rb:108:in `parse_number_format'
     # ./.bundle/ruby/2.7.0/gems/xsv-1.0.2/lib/xsv/sheet_rows_handler.rb:104:in `format_cell'
     # ./.bundle/ruby/2.7.0/gems/xsv-1.0.2/lib/xsv/sheet_rows_handler.rb:60:in `end_element'
     # ./.bundle/ruby/2.7.0/gems/xsv-1.0.2/lib/xsv/sax_parser.rb:68:in `block in parse'
     # ./.bundle/ruby/2.7.0/gems/xsv-1.0.2/lib/xsv/sax_parser.rb:19:in `loop'
     # ./.bundle/ruby/2.7.0/gems/xsv-1.0.2/lib/xsv/sax_parser.rb:19:in `parse'
     # ./.bundle/ruby/2.7.0/gems/xsv-1.0.2/lib/xsv/sheet.rb:64:in `each_row'

I'm guessing this was introduced in c653bb86a019b5de9f00dab5c0261548ff9b457f

It seems the format passed to parse_number_format isn't always a string.

The document was generated by caxlsx.

martijn commented 3 years ago

That's interesting and probably specific to caxlsx. Do you have an example xlsx file you can share, by chance?

jdufresne commented 3 years ago

Here is a minimal test case:

require 'caxlsx'
require 'xsv'

p = Axlsx::Package.new
p.workbook.add_worksheet(name: 'Sheet') do |sheet|
  sheet.add_row [1]
end

workbook = Xsv::Workbook.open(p.to_stream)
workbook.sheets.each do |sheet|
  sheet.each_row do |row|
    p row.inspect
  end
end

This results in the following:

$ bundle exec ruby test.rb
.bundle/ruby/3.0.0/gems/xsv-1.0.2/lib/xsv/helpers.rb:108:in `parse_number_format': undefined method `scan' for nil:NilClass (NoMethodError)
    from .bundle/ruby/3.0.0/gems/xsv-1.0.2/lib/xsv/sheet_rows_handler.rb:104:in `format_cell'
    from .bundle/ruby/3.0.0/gems/xsv-1.0.2/lib/xsv/sheet_rows_handler.rb:60:in `end_element'
    from .bundle/ruby/3.0.0/gems/xsv-1.0.2/lib/xsv/sax_parser.rb:68:in `block in parse'
    from .bundle/ruby/3.0.0/gems/xsv-1.0.2/lib/xsv/sax_parser.rb:19:in `loop'
    from .bundle/ruby/3.0.0/gems/xsv-1.0.2/lib/xsv/sax_parser.rb:19:in `parse'
    from .bundle/ruby/3.0.0/gems/xsv-1.0.2/lib/xsv/sheet.rb:64:in `each_row'
    from test.rb:11:in `block in <main>'
    from test.rb:10:in `each'
    from test.rb:10:in `<main>'

If I run the same script with Xsv 1.0.1, I get:

$ bundle exec ruby test.rb
"[1]"

FWIW, the same generated document opens LibreOffice and Emacs doc-view-mode.

Here is the doc generated by caxlsx:

test.xlsx

jdufresne commented 3 years ago

I suppose this is the relevant row?

<row r="1" ><c r="A1" s="0" t="n"><v>1</v></c></row>
martijn commented 3 years ago

Thank you for the examples, it seems indeed some #nil? checks were lost in c653bb8.

Could you test with the master branch and see if that fixes it?

jdufresne commented 3 years ago

Could you test with the master branch and see if that fixes it?

Yup! All looks good here. Thanks for the very quick response and fix! :tada:

martijn commented 3 years ago

You're welcome! Released Xsv 1.0.3 with the fix