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

Psych::SyntaxError doesn't inherit from StandardError #23

Closed
kunzmann opened this issue Aug 2, 2011 · 8 comments
Closed

Psych::SyntaxError doesn't inherit from StandardError #23

kunzmann opened this issue Aug 2, 2011 · 8 comments

Comments

@kunzmann
Copy link

kunzmann commented Aug 2, 2011

Is this expected behavior?

$ which ruby                  
/Users/kunzmann/.rvm/rubies/ruby-1.9.2-p290/bin/ruby

pysch_error_handling.rb

require 'psych'

begin
  Psych::load("hello:\n  - invalid\nyml")
rescue Psych::SyntaxError
  puts 'can haz error handling?'
end

begin
  Psych::load("hello:\n  - invalid\nyml")
rescue
  puts 'can haz error handling?'
end

produces:

$ ruby psych_error_handling.rb
can haz error handling?
/Users/kunzmann/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:148:in `parse': couldn't parse YAML at line 4 column 0 (Psych::SyntaxError)
    from /Users/kunzmann/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:148:in `parse_stream'
    from /Users/kunzmann/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:119:in `parse'
    from /Users/kunzmann/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:106:in `load'
    from psych_error_handling.rb:10:in `<main>'

I also tried with the following Gemfile:

gem 'psych', '~> 1.2.0'

with this addition to the top of pysch_error_handling.rb:

require 'bundler/setup'

which produces:

$ ruby psych_error_handling.rb
/Users/kunzmann/.rvm/gems/ruby-1.9.2-p290/gems/psych-1.2.0/lib/psych.rb:93: warning: already initialized constant VERSION
/Users/kunzmann/.rvm/gems/ruby-1.9.2-p290/gems/psych-1.2.0/lib/psych.rb:96: warning: already initialized constant LIBYAML_VERSION
can haz error handling?
/Users/kunzmann/.rvm/gems/ruby-1.9.2-p290/gems/psych-1.2.0/lib/psych.rb:154:in `parse': couldn't parse YAML at line 4 column 0 (Psych::SyntaxError)
    from /Users/kunzmann/.rvm/gems/ruby-1.9.2-p290/gems/psych-1.2.0/lib/psych.rb:154:in `parse_stream'
    from /Users/kunzmann/.rvm/gems/ruby-1.9.2-p290/gems/psych-1.2.0/lib/psych.rb:125:in `parse'
    from /Users/kunzmann/.rvm/gems/ruby-1.9.2-p290/gems/psych-1.2.0/lib/psych.rb:112:in `load'
    from psych_error_handling.rb:11:in `<main>'

I guess this is because Psych::SyntaxError doesn't inherit from StandardError. Perhaps that is by design, but it caught me by surprise - so I thought I'd ask.

@tenderlove
Copy link
Member

Yes, this is expected behavior. It is a SyntaxError, so Psych::SyntaxError inherits from SyntaxError.

@chrismcg
Copy link

We too just tripped over this. As SyntaxError is descended from ScriptError and has siblings LoadError and NotImplementedError I'd always assumed it was for Ruby syntax errors only. I think of Psych as a library and was expecting any exceptions it raised to be caught by a rescue of StandardError.

We're handling it now anyways, and I can see your point, but we did find it a bit surprising.

@nirvdrum
Copy link
Contributor

We just got burned by this too. We had some "rescue Exception" to catch things like this, but that wreaked havoc in a multi-threaded environment. It wasn't the best code admittedly, but we tried to do the right thing and just catch StandardError. After three days of debugging, this issue was unearthed. I went to file the issue only to see it had already been closed. While it is a form of syntactical error, I don't think it's anywhere on par with a Ruby SyntaxError. I hope this practice isn't adopted en masse by other data format libraries because you can't reasonably rescue on any class higher up the ancestry without really screwing with Ruby.

@w-A-L-L-e
Copy link

On one of my servers I updated to rails 3.2.3 and I get all these warnings whenever I run a rake task or rails console:

wschrep@Debian-60-squeeze-64-LAMP:/var/www/trouw$ rake db:dump
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant ANY
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF8
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF16LE
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF16BE
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant ANY
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF8
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF16LE
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF16BE
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant ANY
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF8
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF16LE
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF16BE
/usr/local/lib/ruby/1.9.1/x86_64-linux/psych.so: warning: already initialized constant UTF16BE

wschrep@Debian-60-squeeze-64-LAMP:/var/www/trouw$ ruby --version
ruby 1.9.3p125 (2012-02-16) [x86_64-linux]

wschrep@Debian-60-squeeze-64-LAMP:/var/www/trouw$ rails --version
Rails 3.2.3

wschrep@Debian-60-squeeze-64-LAMP:/var/www/trouw$ gem search psych
*** LOCAL GEMS ***
psych (1.3.1)

@senorprogrammer
Copy link

I agree that this is an incorrect use of SyntaxError. The literal description of a SyntaxError is "Raised when encountering Ruby code with an invalid syntax". What Psych is catching is malformed YAML. Different things.

@hynkle
Copy link

hynkle commented Dec 13, 2012

I completely agree with the other commenters saying that Ruby's built-in SyntaxError class is for Ruby code, not for just anything you might be trying to parse. This is evinced by the fact that SyntaxError is a subclass of ScriptError. My YAML is not a script—it is markup, despite having a somewhat chummier relationship with Ruby than other markup formats like JSON or XML. In your view, @tenderlove, is it incorrect to have one's parsing library's parsing exceptions subclass StandardError rather than SyntaxError, or is it just that you don't see any reason not to use SyntaxError since it's there and has such a convenient name?

I've always coded by the rule of thumb that any exception classes I create or exceptions I explicitly raise should subclass StandardError, and that exceptions not descending from StandardError are reserved for the interpreter's use. I haven't noticed anything in any libraries that I use that run counter to that guideline except for Psych::SyntaxError.

It's nice that Psych's parsing exceptions can indeed be explicitly rescued with rescue Psych::SyntaxError or more generally with a rescue Exception, but if I ever have a catch-all rescue (for exception logging or something of that nature), I absolutely do not want to be rescuing the likes of NoMemoryError, SystemExit, SystemStackError, and all the other low-level friends that would be netted by something as general as rescue Exception.

@tenderlove
Copy link
Member

I'm completely convinced of how incorrect I was. Can someone create a patch?

@sodabrew
Copy link

For anyone bit by this issue, it was fixed in commit 66e22be from October 2012. The current rubygems.org release of psych 1.3.4 does not have this fix. @tenderlove Do you know at what point this change was picked up by Ruby 1.9 and/or 2.0?

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

No branches or pull requests

8 participants