Alex Rivera | Logout

raise ActiveRecord::RecordNotFound (or any 404 status) for invalid date

Asked 2010-08-04T17:01:03.840
12

In my controller controller, I have use Date.new to create a date object to be passed in my ActiveRecord.

end_range = Date.new(params[:year].to_i, params[:month].to_i, params[:day].to_i).end_of_day.to_formatted_s(:db)

The problem with this above is that if a user tried to change the parameters in the URL manually, such as entering 40 for the day param, the Date.new fails (as expected). However, I would rather not have a 500 error if a user typed in something like that, but instead a 404 error (because you will never actually be able a record with a day of 40).

I tried various conditionals (if and unless statements) to raise ActiveRecord::RecordNotFound if that fails, but it returns the 500 error before running the conditional (and therefor never returning a 404).

Does anybody know a better way to handle that, or a way to allow the Date.new to fail more gracefully so that the conditional statement can run?

Edit
Report

1 Answer

34

In this case you might rescue one exception and raise another if you'd like to re-map exceptions that aren't handled into the kind that are:

def show
  begin
    end_range = Date.new(...)
  rescue ArgumentError
    # Invalid date
    raise ActiveRecord::RecordNotFound
  end
rescue ActiveRecord::RecordNotFound
  render(:partial => 'not_found', :layout => 'application', :status => :not_found)
end

It might be more efficient to simply render and fail right away though.

def show
  begin
    end_range = Date.new(...)
  rescue ArgumentError
    return render(:partial => 'date_not_found', :layout => 'application', :status => :not_found)
  end
end

You can also do this in a more sweeping sense using the rescue_from method of ApplicationController:

class ApplicationController < ActionController::Base
  rescue_from 'ArgumentError do
    render(:partial => 'exceptions/argument_error', :layout => 'application', :status => :not_found)
  end
end
answered 2010-08-04T17:09:51.090

Your Answer