chazmeyers.com/blog


Slightly better YAMLization of Ruby Exceptions.

Posted in Uncategorized, ruby by chazmeyers on the July 10th, 2007

Consider the following irb session:

Code (ruby)
  1.  
  2. irb(main):001:0> e = Exception.new("Jerk!")
  3. => #<Exception: Jerk!>
  4. irb(main):002:0> e.message
  5. => "Jerk!"
  6. irb(main):003:0> require ‘yaml’
  7. => true
  8. irb(main):004:0> YAML.load(e.to_yaml).message
  9. => "Exception"
  10.  

That sucks. Where did the “Jerk!” go? YAML ate it. If you include this code, you can keep your “Jerk!”:

Code (ruby)
  1.  
  2. cpm@juno:~/helpticket-dev/trunk$ cat lib/better_exception_yaml.rb
  3. require ‘yaml’
  4.  
  5. class Exception
  6.   def Exception.yaml_new( klass, tag, val )
  7.     o = YAML.object_maker( klass, {})
  8.     val.each_pair do |k,v|
  9.       o.instance_variable_set("@#{k}", v)
  10.     end
  11.     o.exception(val["message"])
  12.   end
  13. end
  14.  
  15. cpm@juno:~/helpticket-dev/trunk$ irb
  16. irb(main):001:0> require ‘lib/better_exception_yaml’
  17. => true
  18. irb(main):002:0> YAML.load(Exception.new("JERK").to_yaml).message
  19. => "JERK"
  20.  

It still sucks because the backtrace is not preserved, but that’s because Exception#to_yaml doesn’t serialize that information. YAML was storing the message, but by default it stores it into a @mesg instance variable instead. Quite odd.

I wasn’t inclined enough to read up on the right way to yamlize new data. Maybe later I’ll add backtracing.

Leave a Reply