We talk a lot about error handling in Ruby. But we rarely talk about raising errors and creating helpful error messages that are actionable. A good error should tell the developer what went wrong and what to do about it.
One library is known for its excellent error messages. Consider a typical validation error from Mongoid.
#<Mongoid::Errors::Validations:
Problem:
Validation of User failed.
Summary:
The following errors were found: Password can't be blank
Resolution:
Try persisting the document with valid data or remove the validations.>
This error describes the problem, offers a detailed summary and provides a possible resolution!
Let’s implement a similar system for the ruby-enum gem that I live-coded at NYC.rb.
First, add a dependency on i18n and require “i18n”. Then, create a lib/config/locales folder and an en.yml file in it. English error messages will go there. This file will need to be loaded by our library, specifically in ruby-enum.rb.
Error descriptions inside en.yml contain the problem, summary and resolution. The YAML format supports multi-lines with \_\_
and can include values from parameters using the %{name}
syntax.
The base error class, Ruby::Enum::Errors::Base takes care of the translation. I stripped the implementation details below – the important parts is the BASE_KEY value for localized error messages and the compose_message method. Get the full implementation here and modify it for your project.
Specific errors derive from this class.
When raising an UninitializedConstantError
, pass the values of key and name used in the en.yml file above.
Here’s the result.
1.9.3-p362 :002 > require 'ruby-enum'
=> true
1.9.3-p362 :003 > raise Ruby::Enum::Errors::UninitializedConstantError.new({
:name => "Class",
:key => "CONSTANT"
})
Ruby::Enum::Errors::UninitializedConstantError:
Problem:
Uninitialized constant.
Summary:
The constant Class::CONSTANT has not been defined.
Resolution:
The enumerated value could not be found in class Class.
Use 'define' to declare it.
Example:
module Class
include Ruby::Enum
define CONSTANT, 'value'
end
Beautiful.