Создание страницы ошибки для ошибки 422

В настоящее время я генерирую динамические страницы ошибок для 500 и 404 ошибок. Я хочу расширить это до 422 ошибок. Вот что мы имеем до сих пор.

конфиг / application.rb

config.exceptions_app = self.routes

Контроллеры / errors_controller.rb

class ErrorsController < ApplicationController
  def not_found
    render status: 404
  end

  def internal_server_error
    render status: 500
  end

  def unacceptable
    render status: 422
  end
end

routes.rb

get '/404' => 'errors#not_found'
get '/500' => 'errors#internal_server_error'
get '/422' => 'errors#unacceptable'

Публичная страница /422.html была удалена. Страницы просмотра ошибок были созданы, но для краткости опущены. При возникновении ошибки 404 или 500 отображаются страницы ошибок. Однако, когда я получаю ошибку 422, я получаю следующую страницу ошибки.

Я видел множество учебных пособий, реализующих этот же подход, и он работает. Однако я получаю сгенерированную ошибку Rails, а не страницу с ошибкой, которую я создал. Что не так и как мне это исправить?

Учебники, на которые я смотрел:

1 ответ

Решение

Я еще один разработчик, который работал над этим с @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. InvalidAuthenticityToken

Но поскольку общая причина 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 ошибки в том же запросе.

Другие вопросы по тегам