Catching errors is quite a normal thing when writing code, every programing language has some variation of the throw/catch, in Ruby's case, it's the elegant begin, rescue and ensure blocks.
At some point in every project you stop catching "other" people's errors and start catching your own.
So you start creating you own error classes, there's a couple common approaches I've seen over the years.
- Create an Errors namespace on each class/module you need and create errors for that there.
- Create a generic Project::Errors with its own file bag and throw all errors in there.
I usually go for the second approach, so error classes don't distract me, but that's more of a personal preference anyway.
However, I am a lazy bum and I've got tired of specified my error classes, so I made this Gist as an example:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#The following two examples are equivalent | |
#Example 1, explicit error classe declaration | |
class MyMainNamespace | |
module Errors | |
class Error1 < StandardError; end | |
class Error2 < StandardError; end | |
end | |
end | |
#Example 2, use const_missing for maximum lazyness | |
class MyMainNamespace | |
module Errors | |
def self.const_missing class_name | |
self.const_set( class_name , Class.new( StandardError ) ) | |
self.const_get( class_name ) | |
end | |
end | |
end | |
#usage: | |
being | |
do_something | |
rescue MyMainNamespace::Errors::Error1 | |
do_something_else | |
rescue MyMainNamespace::Errors::Error2 | |
do_something_different | |
#only works with second example, throws an invalid constant Error404 otherwise | |
rescue MyMainNamespace::Errors::Error404 | |
error_not_found | |
end | |
The main idea behind this, is letting you freely type your errors as you need them both where they're being raised and rescued and you don't need to worry about they existing since they'll be created in runtime for you.
This method is probably not very efficient, but I don't care for this case.