поднять ActiveRecord :: RecordNotFound (или любой статус 404) для недопустимой даты - PullRequest
11 голосов
/ 04 августа 2010

В моем контроллере контроллера я использую Date.new для создания объекта даты, который будет передан в мой ActiveRecord.

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

Проблема с этим выше заключается в том, что если пользователь попытался изменить параметры в URL-адресе вручную, например, введя 40 для параметра дня, Date.new завершится неудачно (как и ожидалось). Тем не менее, я бы предпочел не иметь ошибку 500, если пользователь набрал что-то подобное, а вместо этого ошибку 404 (потому что на самом деле вы никогда не сможете получить запись с днем ​​40).

Я пробовал различные условные выражения (if и unless операторы) до raise ActiveRecord::RecordNotFound, если это не удалось, но он возвращает ошибку 500 до запуска условного выражения (и, следовательно, никогда не возвращает 404).

Кто-нибудь знает лучший способ справиться с этим или способ более изящного сбоя Date.new для выполнения условного оператора?

Ответы [ 2 ]

30 голосов
/ 04 августа 2010

В этом случае вы можете спасти одно исключение и вызвать другое, если вы хотите переназначить исключения, которые не обрабатываются в виде:

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

Возможно, было бы эффективнее просто выполнить рендеринг и сразу потерпеть неудачу.

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

Вы также можете сделать это в более широком смысле, используя rescue_from метод ApplicationController:

class ApplicationController < ActionController::Base
  rescue_from 'ArgumentError do
    render(:partial => 'exceptions/argument_error', :layout => 'application', :status => :not_found)
  end
end
1 голос
/ 27 апреля 2011

Я думаю, что имеет смысл спасти недопустимую ошибку даты с помощью полезного сообщения.Это общая проблема, когда люди выбирают 30 февраля, например.Я бы лучше отправил их обратно в форму и сказал, почему их отправляют обратно.404 будет неправильным в большинстве случаев, так как ошибка неверный ввод пользователя, а не недействительный URL.

Кроме того, если вы спасете все ArgumentError s, вы не будете получать уведомления о других кодахошибок.Так что, если это не ошибка даты, то я заново поднимаю ошибку.К сожалению, мы должны изменить тип исключения, чтобы избежать цикла.

Я поместил это в application_controller:

rescue_from ArgumentError do |exception|
  if exception.message == 'invalid date'
    flash[:error] = exception.message
    redirect_to request.referer ? :back : root_url
  else
    raise StandardError, exception.message, exception.backtrace
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...