Search code examples
ruby-on-rails-3error-handlingcustom-exceptions

Getting a list of existing Rails Error classes for re-use/inheritance


Often I need to throw a custom(ized) error. Like when a resource cannot be found due to a mismatch in parameters or so.

I prefer to throw existing errors or, throw an error that is inherited from an existing error. That way, I don't introduce Error classes that were already defined and could have been used perfectly (DRY). But it also allows to keep wording and style the same, by inheriting and simply changing a word or two to clarify the difference with the original Error.

For example:

Foo.new
Foo.some_external_id = nil
Foo.fetch_external_resource
# => InvalidOptions: Calling Foo#fetch_external_resource with nil is invalid

I am quite sure such errors are already defined. In fact, after reading trough many lines of code, I found my MongoID driver has Mongoid::Errors::InvalidOptions: Calling Document#find with nil is invalid.

Is there a list of available Error classes in Ruby Core and Ruby on Rails? Is there a way to get such a list for your current project?

Is it smart at all to re-use and/or inherit existing errors, or should I maintain my own, custom set instead?


Solution

  • There's a mostly adequate solution here: http://www.ruby-forum.com/topic/158088

    Since this question is unanswered, yet coming up at the top of Google search results, I decided to wrap Frederick Cheung's solution up in a rake task and post it here.

    Drop the following in lib/tasks/exceptions.rake

    namespace :exceptions do
      task :list => :environment do
        exceptions = []
    
        ObjectSpace.each_object(Class) do |k|
          exceptions << k if k.ancestors.include?(Exception)
        end
    
        puts exceptions.sort { |a,b| a.to_s <=> b.to_s }.join("\n")
      end
    end
    

    Run it with:

    bundle exec rake exceptions:list
    

    If you're still on Rails 2, or not using Bundler, leave off the bundle exec

    This list is probably adequate, but not exhaustive. For example, ActiveResource defines several exceptions such as ActiveResource::ConnectionError and ActiveResource::TimeoutError that are not appearing when I run this task. Maybe someone else can enlighten me as to why.