Внутренняя ошибка сервера 500 выбрасывается вместо 404 при попытке доступа к сломанным URL-адресам

У нас есть сервер rails с настраиваемой настройкой 404 и 500 страниц, используя этот учебник здесь:

http://ramblinglabs.com/blog/2012/01/rails-3-1-adding-custom-404-and-500-error-pages

Пока он работает хорошо и выбрасывает 404s для всех видов путей, он генерирует внутренние ошибки сервера 500, пытаясь получить доступ к любому типу суффикса, например en/foo.png, en/foo.pdf, en/foo.xml,...

Но что-то вроде en/file.foo выбрасывает 404. Таким образом, только действительные суффиксы бросают 500.

Конец маршрута .rb:

if Rails.application.config.consider_all_requests_local
  match '*not_found', to: 'errors#error_404'
end

application_controller.rb

  unless Rails.application.config.consider_all_requests_local
    rescue_from Exception, with: :render_500
    rescue_from ActionController::RoutingError, with: :render_404
    rescue_from ActionController::UnknownController, with: :render_404
    rescue_from ::AbstractController::ActionNotFound, with: :render_404
    rescue_from ActiveRecord::RecordNotFound, with: :render_404
  end

  protected

  def render_404(exception)
    @not_found_path = exception.message
    respond_to do |format|
      format.html { render template: 'errors/error_404', layout: 'layouts/application', status: 404 }
      format.all { render nothing: true, status: 404 }
    end
  end

  def render_500(exception)
    logger.fatal(exception)
    respond_to do |format|
      format.html { render template: 'errors/error_500', layout: 'layouts/application', status: 500 }
      format.all { render nothing: true, status: 500}
    end
  end

500:

Missing template errors/error_404 with {:locale=>[:de, :en], :formats=>[:png], :handlers=>[:erb, :builder, :coffee, :arb, :haml]}

Ответ 1

Мы нашли ошибку.

У нас был error_controller.rb, содержащий это:

  def error_404
    @not_found_path = params[:not_found]
    render template: 'errors/error_404', layout: 'layouts/application', status: 404
  end

и мы изменили его, чтобы исправить эту проблему:

  def error_404
    @not_found_path = params[:not_found]
    respond_to do |format|
      format.html { render template: 'errors/error_404', layout: 'layouts/application', status: 404 }
      format.all { render nothing: true, status: 404 }
    end
  end

Ответ 2

Попробуйте добавить

respond_to :html, :json, :png

и любые другие необходимые форматы в верхней части вашего контроллера. Если я прав, то проблема в том, что format.all в отдельных действиях контроллера не настроен, чтобы включить :png в качестве одного из форматов, на которые он отвечает.

Вам, вероятно, также потребуется добавить к вашему config/environment.rb следующее определение и любые другие:

Mime::Type.register "image/png", :png

Подробнее здесь. В основном вам нужно настроить типы mime, на которые вы хотите ответить. Сообщение об ошибке указывает, что рельсы не понимают, как отобразить формат png.