Enhanced error messages when hash keys are missing

Hash#fetch is a great way to ensure that a hash key is present. The error message when a key is missing though is rather useless if you don't have immediate access to the object and want to debug why keys are missing, e.g. in the parsed JSON response of an external API. If you'd like a more detailed error message, you can do a Hash#decent_fetch (with the attached code).

some_hash.fetch('missing_key')
# => KeyError: key not found: "missing_key"
 
some_hash.decent_fetch('missing_key')
# => KeyError: Key "missing_key" not found in {"id"=>"96814974590_10152840169159591", "created_time"=>"2014-11-18T20:30:41+0000", "story"=>"Audi Deutschland commented on a photo."}

You could put this code in an initializer:

# E.g. config/initializers/hash_decent_fetch.rb.rb
Hash.class_eval do

  def decent_fetch(*args, &block)
    fetch(*args, &block)
  rescue KeyError
    key = args.first
    raise KeyError, "Key #{key.inspect} not found in #{self.inspect}"
  end

end

If you are now thinking about monkey-patching Hash#fetch with this code, please do not do that. The implementation is slower than vanilla #fetch. Use #decent_fetch only when applicable, e.g. when consuming APIs.

Thomas Klemm Over 9 years ago