rails 4: пользовательские страницы ошибок для 404, 500 и откуда приходит сообщение об ошибке 500 по умолчанию?
В настоящее время в производстве я получаю этот текст:
500 Internal Server Error
If you are the administrator of this website, then please read this web application's
log file and/or the web server's log file to find out what went wrong.
нет html на этой странице ничего.
где находится этот код? У меня есть нет public / 500.HTML или что-нибудь в этом отношении.
в моих маршрутах у меня есть:
get "/404", :to => "errors#error_404"
get "/422", :to => "errors#error_404"
get "/500", :to => "errors#error_500"
get "/505", :to => "errors#error_505"
ErrorsController:
class ErrorsController < ApplicationController
def sub_layout
"left"
end
def error_404
render :status => 404, :formats => [:html], :layout => "white", :sub_layout => "left"
end
def error_422
render :status => 422, :formats => [:html], :layout => "white", :sub_layout => "left"
end
def error_500
render :status => 500, :formats => [:html], :layout => "white", :sub_layout => "left"
end
def error_505
render :status => 505, :formats => [:html], :layout => "white", :sub_layout => "left"
end
end
как заставить его загружать мои пользовательские ошибки всегда? На некоторых ошибках он просто бросает этот 2-строчный текст, идущий где-то из ядра rails, я хочу, чтобы он взял мой обычай стилизованные страницы ошибок каждый раз! как? спасибо!
4 ответов:
ошибка, которую вы испытываете, выбрасывается из
это означает, что код, который ваши исключения спасают, сами выбрасывают исключения. Вы можете проверить свои журналы для текста:
Error during failsafe response:чтобы определить, что исключения действительно происходят из и, таким образом, решить ваши проблема.
обновить 2018
наши
exception_handlergem теперь считается самым популярным (Rails custom error pages) ↴
Как Это Работает
все исключения Rails обрабатываются с помощью
config.exceptions_app. Это назначается вconfig/application.rbилиconfig/environments/*.rbфайлы - это должно быть обратный вызов:
всякий раз, когда Rails попадает в ошибку, он вызывает
ShowExceptionsmiddleware. Это вызываетexception_appи посылает весьrequest(включаяexception) кexceptions_app:
exceptions_appнужно передать ответ. Если нет, тоfailsafeзагружено:# show_exceptions.rb#L38 def render_exception(env, exception) wrapper = ExceptionWrapper.new(env, exception) status = wrapper.status_code env["action_dispatch.exception"] = wrapper.exception env["PATH_INFO"] = "/#{status}" response = @exceptions_app.call(request.env) # => exceptions_app callback response[1]["X-Cascade"] == "pass" ? pass_response(status) : response rescue Exception => failsafe_error # => raised if exceptions_app false $stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}" FAILSAFE_RESPONSE endThe
failsafeэто хранится какFAILSAFE_RESPONSEв верхней частиShowExceptions.
Пользовательские Страницы Ошибок
если вы хотите создать пользовательские страницы ошибок, вам нужно ввести свой собственный обратный вызов в
config.exceptions_app. Это может быть сделано либо в приложении, либо с драгоценным камнем:
обратите внимание, как
callметод используется-вот как работает обратный вызов. Рельсы (env) вызывается, когда запрос получен от Интернет; когда возникает исключение,envперешло кexceptions_app.качество обработки исключений будет зависеть от того, как вы управляете
env. Это важно; ссылкаself.routesтут не переносите окружающую среду вперед.лучший способ-обрабатывать исключения с помощью отдельного контроллера. Это позволяет обрабатывать запрос, как если бы это был просто другой вид, предоставляя доступ к
layoutи других компонентов (model/--
здесь два способы обработки исключений:
- переопределение
404/500маршруты- вызов контроллера
наш драгоценный камень был разработан вокруг нашего
controller- вызывается каждый разexceptionподнимается. Это дает полное контроль над процессом исключения, что позволяет 100% фирменная макет:
ExceptionHandlerв настоящее время является ведущим производством пользовательских страниц ошибок gem для рельсов.поддержанный на сверх 3 лет, самый простой и самый сильный самоцвет исключения для рельсов. Он работает на 100% на Rails 5 и уже был загружен более 70 000 раз.
камень
последние ver
0.8.0.0имеет следующие обновления:
- пользовательские исключения
- исключение "сопоставление" (выберите, какие исключения для обработки)
- уведомления по электронной почте
- модель backend
- звездочки 4+ интеграция
- Для RSpec Тестов
- представления на основе локали
вы можете подробнее здесь.
Управление Исключениями Рельсов
если вы не заинтересовавшись драгоценным камнем, позвольте мне объяснить процесс:
все исключения Rails обрабатываются с помощью
config.exceptions_appобратный. Это назначается вconfig/application.rbилиconfig/environments/*.rbфайлы - это должен быть обратный вызов:
всякий раз, когда исключение создается вашим приложением,
ShowExceptionsвызывается промежуточное программное обеспечение. Это промежуточное программное обеспечение создает исключение вrequestи переправляет его вconfig.exceptions_appобратный звонок.по умолчанию
config.exceptions_appуказывает на маршрутах. Вот почему Rails поставляется с404.html,500.htmlи422.htmlна .если вы хотите создать custom страницы исключений, вам нужно переопределить
config.exceptions_appобратный вызов-передача ошибочного запроса соответствующему обработчику, будь тоcontrollerилиroute:[[middleware ]]
два способа эффективно управлять либо отправить ошибочные запросы к маршрутам, или для вызова контроллера.
самый простой и наиболее распространенный способ-переадресация запроса на маршруты; к сожалению, это игнорирует запрос и мешает вам правильно детализировать исключения.
лучший способ-вызвать отдельный контроллер. Это позволит вам передать весь запрос, что позволит вам сохранить его, отправить его по электронной почте или сделать ряд других вещей.
--
400 / 500 Ошибки
рельсы только ответить с HTTP-допустимыми ошибками.
в то время как приложения исключение может отличаться, возвращаемый код состояния должны либо
40xили50x. Это соответствует спецификации HTTP и изложено здесь↴
это означает, что независимо от того, какое решение обработки исключений вы используете / build, Rails должен вернуть
40xили50xошибки в браузере.другими словами, пользовательские страницы ошибок имеют мало общего с тип исключения-больше, как вы ловите и обслуживаете ответ браузер.
по умолчанию Rails делает это с
404.html,422.htmlи500.htmlфайлы . Если вы хотите самостоятельно обработать поток исключений, вам необходимо удалить эти файлы и направляйте ошибочные запросы на свой собственныйexceptions_appобратный.это можно сделать с помощью тега
routesилиcontroller(что я сейчас объясню):
1. Маршруты
самый простой способ-позволить маршрутам справиться с этим.
этот метод раздут и требует использования нескольких действий. Также трудно управлять ответами.
в этом уроке объясняет:
это показывает, как заменить
exceptions_appс маршрутами напрямую:# config/application.rb config.exceptions_app = self.routesвот код, который у меня есть (Ruby 2.0.0, Rails 4.0):
Конфигурации
#config/application.rb config.exceptions_app = self.routesмаршруты
#config/routes.rb if Rails.env.production? get '404', to: 'application#page_not_found' get '422', to: 'application#server_error' get '500', to: 'application#server_error' endКонтроллер Приложения
#controllers/application_controller.rb def page_not_found respond_to do |format| format.html { render template: 'errors/not_found_error', layout: 'layouts/application', status: 404 } format.all { render nothing: true, status: 404 } end end def server_error respond_to do |format| format.html { render template: 'errors/internal_server_error', layout: 'layouts/error', status: 500 } format.all { render nothing: true, status: 500} end endОшибки Разметки (полностью статический-для сервера только ошибки)
#views/layouts/error.html.erb <!DOCTYPE html> <html> <head> <title><%= action_name.titleize %> :: <%= site_name %></title> <%= csrf_meta_tags %> <style> body { background: #fff; font-family: Helvetica, Arial, Sans-Serif; font-size: 14px; } .error_container { display: block; margin: auto; margin: 10% auto 0 auto; width: 40%; } .error_container .error { display: block; text-align: center; } .error_container .error img { display: block; margin: 0 auto 25px auto; } .error_container .message strong { font-weight: bold; color: #f00; } </style> </head> <body> <div class="error_container"> <%= yield %> </div> </body> </html>Вид Ошибки
#views/errors/not_found_error.html.erb <div class="error"> <h2>Sorry, this page has moved, or doesn't exist!</h2> </div> #views/errors/internal_server_error.html.erb <div class="error"> <div class="message"> <strong>Error!</strong> We're sorry, but our server is experiencing problems :( </div> </div>хотя многие предпочитают метод "маршрутов" для его простоты, он не является ни эффективным, ни модульным. Действительно, если ваше приложение имеет какое-либо подобие объектной ориентации, вы быстро отклоните его как хак.
A много более громкий способ-использовать пользовательский контроллер, чтобы поймать чистое исключение. Таким образом, вы можете построить поток в соответствии с вашим общая структура приложения:
2. Контроллер
другой вариант заключается в маршрутизации всех запросов к контроллеру.
это бесконечно более мощный, поскольку он позволяет вам взять запрос (исключение) и передать его в представления, управляя им в бэкэнде. Это позволит для подобных сохранения его в базе данных.
этой суть показывает как:
это означает, что мы можем подключиться к промежуточному программному обеспечению и передать весь запрос контроллер.
если этот контроллер поддерживается моделью и представлениями, мы можем извлечь его в драгоценный камень (что мы и сделали). Если вы хотите сделать это вручную, вот как:
--
Config
красота этого метода заключается в том, что он подключается непосредственно в
config.exceptions_app. Это означает, что любое исключение может быть обработано изначально, что позволяет повысить эффективность. Чтобы убедиться, что это работает, вам нужно поместить следующий код вconfig/application.rb(exceptions_appработает только вproduction-developmentпоказывает ошибки):#config/application.rb config.exceptions_app = ->(env) { ExceptionController.action(:show).call(env) }чтобы проверить, вы можете установить "локальные" запросы в false:
#config/environments/development.rb config.consider_all_requests_local = false # true--
контроллер
следующим шагом является добавление
exceptionконтроллер. Хотя это может быть обработано вapplication_controller, это гораздо лучше добывать в свой собственный. Обратите внимание на звонок отapplication.rb--ExceptionController.action(:show):#app/controllers/exception_controller.rb class ExceptionController < ApplicationController #Response respond_to :html, :xml, :json #Dependencies before_action :status #Layout layout :layout_status #################### # Action # #################### #Show def show respond_with status: @status end #################### # Dependencies # #################### protected #Info def status @exception = env['action_dispatch.exception'] @status = ActionDispatch::ExceptionWrapper.new(env, @exception).status_code @response = ActionDispatch::ExceptionWrapper.rescue_responses[@exception.class.name] end #Format def details @details ||= {}.tap do |h| I18n.with_options scope: [:exception, :show, @response], exception_name: @exception.class.name, exception_message: @exception.message do |i18n| h[:name] = i18n.t "#{@exception.class.name.underscore}.title", default: i18n.t(:title, default: @exception.class.name) h[:message] = i18n.t "#{@exception.class.name.underscore}.description", default: i18n.t(:description, default: @exception.message) end end end helper_method :details #################### # Layout # #################### private #Layout def layout_status @status.to_s == "404" ? "application" : "error" end end--
вид
есть два вида, чтобы добавить, чтобы получить эту работу.
первое-это
exception/showвид, а во-вторых этоlayouts/error. Во-первых, чтобы датьexception_contoller#showвид, а второй для500внутренние ошибки сервера.#app/views/exception/show.html.erb <h1><%= details[:name] %></h1> <p><%= details[:message] %></p> #app/views/layouts/error.html.erb (for 500 internal server errors) <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Error</title> <style> html { height: 100%; background: #fff; } body { font-family: Helvetica, Arial, Sans-Serif; font-size: 14px; } .error_container { display: block; margin: auto; margin: 10% auto 0 auto; width: 40%; } .error_container .error { display: block; text-align: center; } .error_container .error img { display: block; margin: 0 auto 15px auto; } .error_container .message > * { display: block; } .error_container .message strong { font-weight: bold; color: #f00; } </style> </head> <body> <div class="error_container"><%= yield %></div> </body> </html>
вывод
в исключение не имеет значения, как код ошибки.
когда Rails вызывает исключение, он назначает один из вышеперечисленных
HTTPкоды ответов. Они позволяют вашему браузеру определить, был ли запрос успешным.при работе с исключениями, вы должны убедиться, что вы в состоянии обрабатывать
40*ошибки (которые обычно используют тот же макет, что и остальная часть вашего приложения) и50*ошибки (которые понадобятся свои макет.)в обоих случаях, вы будете лучше использовать отдельную
exceptionконтроллер, который позволит вам управлятьexceptionкак объект.
страницы ошибок в приложении должны быть максимально простыми. Та же рекомендация касается их оказания. Если ваше приложение возвращает 500 HTTP-код ответа, это означает, что все уже пошло не так. И есть вероятность, что вы не смогли отобразить страницу ошибки и отобразить ее пользователю.
В идеале страницы ошибок должны быть простым HTML, обслуживаемым непосредственно вашим веб-сервером, не задев сервер приложений.
говоря о рельсах реализации этой идеи. Он основан на использование конвейера активов для предварительной компиляции статических страниц HTML.
Сначала добавьте новый тип активов (Rails > 4.1):
# config/initializers/assets.rb Rails.application.config.assets.precompile += %w(404.html 500.html) Rails.application.config.assets.paths << Rails.root.join('app/assets/html') Rails.application.config.assets.register_mime_type('text/html', '.html')если используется механизм шаблонов (например, slim, haml), зарегистрируйте его через инициализатор:
# for Slim Rails.application.assets.register_engine('.slim', Slim::Template) # for Haml Rails.application.assets.register_engine('.haml', Tilt::HamlTemplate)теперь вы готовы создавать красивые страницы ошибок в каталоге app/assets/html с помощью ваш любимый шаблон двигателя и рельсы встроенный вид помощников.
советы по производству
на конвейере производственных активов добавляет дайджест скомпилированные активы и файлы хранятся в папке по умолчанию (обычно общие/общедоступные / активы на рабочем сервере). Вы можете использовать capistrano для копирования страниц ошибок в корень веб-сервера:
# config/deploy.rb # Capistrano 3 only namespace :deploy do desc 'Copy compiled error pages to public' task :copy_error_pages do on roles(:all) do %w(404 500).each do |page| page_glob = "#{current_path}/public/#{fetch(:assets_prefix)}/#{page}*.html" # copy newest asset asset_file = capture :ruby, %Q{-e "print Dir.glob('#{page_glob}').max_by { |file| File.mtime(file) }"} if asset_file execute :cp, "#{asset_file} #{current_path}/public/#{page}.html" else error "Error #{page} asset does not exist" end end end end after :finishing, :copy_error_pages endи последнее. Попросите веб-сервер использовать эти файлы для определенных кодов ошибок HTTP (пример конфигурации nginx):
error_page 500 502 503 504 /500.html; error_page 404 /404.html;Звездочка 3 Обновление
для Звездочки 3 вам нужно что-то вроде этого (проверено с рельсами 5):
# config/environments/production.rb config.assets.configure do |env| env.register_transformer 'text/slim', 'text/html', Slim::Template env.register_mime_type 'text/slim', extensions: ['.html'] env.register_engine '.slim', Slim::Template end # config/initializers/assets.rb Rails.application.config.assets.precompile += %w(404.html 500.html) Rails.application.config.assets.paths << Rails.root.join('app/assets/html')
вот последнее и быстрое исправление для показа страницы custom 404_error.
- добавить ниже строки развитие.РБ или производства.РБ в своем env.
config.exceptions_app = self.маршруты
config.consider_all_requests_local = false
- удалить все RM public / {404,500,422}.HTML-код
- создать 404.формат html.Эрб file in статический папка вашего проекта rails. Вы можете добавить свой собственный html здесь.(это будет использовать макет приложения, поэтому не беспокойтесь о содержании верхнего и нижнего колонтитулов)










Comments