Helpful Named-Route Error Messages

January 4, 2008 Pivotal Labs

Sometimes I call a named route incorrectly: edit_user_project_path(project). And I get an illegible error message:

user_project_url failed to generate from {:action=>"show", :user_id=>#<Project id: 1, name: "Andy falls off a cliff", created_at: "2007-12-03 15:15:08", creator_id: 2, completed_at: nil, description: "", deleted_at: nil>, :controller=>"projects"}, expected: {:action=>"show", :controller=>"projects"}, diff: {:user_id=>#<Project id: 1, name: "Andy falls off a cliff", created_at: "2007-12-03 15:15:08", creator_id: 2, completed_at: nil, description: "", deleted_at: nil>}

I can’t read that. This, however, is much clearer:

user_project_url failed to generate from {:action=>"show", :user_id=>"1", :controller=>"projects"}, expected: {:action=>"show", :controller=>"projects"}, diff: {:user_id=>"1"}

The error message really ought to call #to_param on the path parts, don’t you think?

class ActionController::Routing::RouteSet
  # try to give a helpful error message when named route generation fails
  def raise_named_route_error(options, named_route, named_route_name)
    helpful_options = options.inject({}) {|hash, (key, value)| hash.merge(key => value.to_param) }
    diff = named_route.requirements.diff(options)
    unless diff.empty?
      raise RoutingError, "#{named_route_name}_url failed to generate  from #{helpful_options.inspect}, expected:  #{named_route.requirements.inspect}, diff:  #{named_route.requirements.diff(helpful_options).inspect}"
    else
      required_segments = named_route.segments.select {|seg| (!seg.optional?) && (!seg.is_a?(DividerSegment)) }
      required_keys_or_values = required_segments.map { |seg| seg.key rescue seg.value } # we want either the key or the value from the segment
      raise RoutingError, "#{named_route_name}_url failed to generate from #{helpful_options.inspect} - you may have ambiguous routes, or you may need to supply additional parameters for this route.  content_url has the following required parameters: #{required_keys_or_values.inspect} - are they all satisfied?"
    end
  end
end

Make it so!

About the Author

Biography

More Content by Pivotal Labs
Previous
The Power of Versions (Monkey Patches Targeted with Friggin Laser Beams!)
The Power of Versions (Monkey Patches Targeted with Friggin Laser Beams!)

We all love to Monkey Patch Rails and other Ruby apps. However, we sometimes want to target these patches ...

Next
alias_method_chain :validates_associated, :informative_error_message
alias_method_chain :validates_associated, :informative_error_message

I dislike the vague error message produced by validates_associated. class User validates_associated :pro...

Enter curious. Exit smarter.

Register Now