Ruby custom error classes: inheritance of the message attribute

MarioDS picture MarioDS · Apr 19, 2013 · Viewed 64.6k times · Source

I can't seem to find much information about custom exception classes.

What I do know

You can declare your custom error class and let it inherit from StandardError, so it can be rescued:

class MyCustomError < StandardError
end

This allows you to raise it using:

raise MyCustomError, "A message"

and later, get that message when rescuing

rescue MyCustomError => e
  puts e.message # => "A message"

What I don't know

I want to give my exception some custom fields, but I want to inherit the message attribute from the parent class. I found out reading on this topic that @message is not an instance variable of the exception class, so I'm worried that my inheritance won't work.

Can anyone give me more details to this? How would I implement a custom error class with an object attribute? Is the following correct:

class MyCustomError < StandardError
  attr_reader :object
  def initialize(message, object)
    super(message)
    @object = object
  end
end

And then:

raise MyCustomError.new(anObject), "A message"

to get:

rescue MyCustomError => e
  puts e.message # => "A message"
  puts e.object # => anObject

will it work, and if it does, is this the correct way of doing things?

Answer

Stefan picture Stefan · Apr 19, 2013

raise already sets the message so you don't have to pass it to the constructor:

class MyCustomError < StandardError
  attr_reader :object

  def initialize(object)
    @object = object
  end
end

begin
  raise MyCustomError.new("an object"), "a message"
rescue MyCustomError => e
  puts e.message # => "a message"
  puts e.object # => "an object"
end

I've replaced rescue Exception with rescue MyCustomError, see Why is it a bad style to `rescue Exception => e` in Ruby?.