Я еще один разработчик, который работал над этим с @jason328. Оказалось, что это проблема, состоящая из нескольких частей, сначала с общими ошибками 422, а затем с конкретным сценарием, в котором Rails поднимал ActiveRecord::InvalidAuthenticityToken
и не отображал соответствующую страницу.
1. Общие ошибки 422
Страница ошибки Rails
Мы временно избавились от этого в нашей локальной среде разработки, установив config.consider_all_requests_local = false
. Но затем вместо нашей пользовательской страницы с ошибкой мы получили пустую белую страницу.
Пустая белая страница
В соответствии с этим вопросом о переполнении стека мы нужен match '/422', to: 'errors#unprocessable_entity', via: :all
для маршрута вместо get '/422' => 'errors#unprocessable_entity'
.
На данный момент общие ошибки 422 выполняются так, как должны. Мы настроили действие контроллера, которое поднимало ActiveRecord::InvalidAuthenticityToken
, как только вы его нажимали, и отображало нашу пользовательскую страницу 422. Так что для тех, у кого просто есть проблемы с ошибками 422 в целом, вышеизложенное должно помочь вам.
2. Недействительный токен подлинности
Но поскольку распространенной причиной ошибок 422 на самом деле является получение ошибки InvalidAuthenticityToken
в дикой природе, кажется, стоит описать остальную часть проблемы, с которой мы столкнулись. В реальном сценарии, когда приложение генерировало собственную ошибку InvalidAuthenticityToken
, теперь мы получали только текстовую ошибку 500 вместо нашей пользовательской страницы 422.
Только текст 500 ошибка
Мы смогли отследить это до FAILSAFE_RESPONSE
в ActionDispatch::ShowExceptions#render_exception
. Именно здесь Rails берет сгенерированное исключение и преобразует его в массив ответов [status, body, headers]
. Если в это время возникает другое исключение, а не попадание в бесконечный цикл, оно сдается и возвращает FAILSAFE_RESPONSE. В этом случае при составлении ответа возникла еще одна ошибка InvalidAuthenticityToken
.
В этот момент пришло время для стратегии :rescue_from
:
rescue_from ActionController::InvalidAuthenticityToken,
with: :rescue_invalid_authenticity_token
def rescue_invalid_authenticity_token
#...notify services as if this error weren't being rescued
redirect_to '/422'
end
с перенаправлением, чтобы уберечь нас от дальнейших InvalidAuthenticityToken
ошибок в том же запросе.
person
arthurlewis
schedule
13.01.2017
rescue_from
? - person tadman   schedule 10.01.2017rescue_from
. Я опубликую ссылки на учебники, которые я просмотрел в своем вопросе. - person thank_you   schedule 10.01.2017rescue_from
, и он работает безупречно. Я надеялся, что мне не придется использоватьrescue_from
в первую очередь. Ни в одном другом учебнике этот подход не упоминается, и если бы я мог избавиться отrescue_from
и метода, который он вызывает, я бы упростил свой код. - person thank_you   schedule 11.01.2017config.exceptions_app = self.routes
может быть проще выполнять свою работу и просто перенаправлять пользователя на страницу с ошибкой 422. Я исследовал и нашел эти статьи. Ни один из них не используетrescue_from
, что заставило меня подумать, что должен быть другой способ сделать это. Но из того, что вы говорите, единственный путь к такому - черезrescue_from
. - person thank_you   schedule 11.01.2017rescue_from
— это наименее удивительный и наименее запутанный способ сделать это. Может быть, вы можете добавить сюда ответ, который объясняет ваше решение и ваши сомнения по поводу того, чтобы пойти по этому пути, чтобы другие могли лучше понять. - person tadman   schedule 11.01.2017rescue_from
- правильный ответ. Я добавлю ответ через два дня, когда у меня будет возможность сделать это. - person thank_you   schedule 11.01.2017rescue_from
не всегда рекламировался так хорошо, как следовало бы. - person tadman   schedule 11.01.2017