chore: custom dynamic & static 500 pages

This commit is contained in:
Colin Darie 2024-04-08 23:26:20 +02:00
parent 7dcd4ba538
commit 5d23b37f59
No known key found for this signature in database
GPG key ID: 8C76CADD40253590
9 changed files with 2274 additions and 51 deletions

View file

@ -3,7 +3,40 @@
class ErrorsController < ApplicationController
def nav_bar_profile = try_nav_bar_profile_from_referrer
def not_found
render(status: 404)
rescue_from Exception do
# catch any error, except errors triggered by middlewares outside controller (like warden middleware)
render file: Rails.public_path.join('500.html'), layout: false, status: :internal_server_error
end
def internal_server_error
# This dynamic template is rendered when a "normal" error occurs, (ie. a bug which is 99.99% of errors.)
# However if this action fails (error in the view or in a middlewares)
# the exceptions are rescued and a basic 100% static html file is rendererd instead.
render_error 500
end
def not_found = render_error 404
private
def render_error(status)
respond_to do |format|
format.html { render status: }
format.json { render status:, json: { status:, name: Rack::Utils::HTTP_STATUS_CODES[status] } }
end
end
# Intercept errors in before_action when fetching user or roles
# when db is unreachable so we can still display a nice 500 static page
def current_user
super
rescue
nil
end
def current_user_roles
super
rescue
nil
end
end

View file

@ -0,0 +1,19 @@
%main#content{ role: "main" }
.fr-container
.fr-my-7w.fr-mt-md-12w.fr-mb-md-10w.fr-grid-row.fr-grid-row--gutters.fr-grid-row--middle.fr-grid-row--center
.fr-py-0.fr-col-12.fr-col-md-6
%h1 Unexpected Error
%p.fr-text--sm.fr-mb-3w Error 500
%p.fr-text--lead.fr-mb-3w
Sorry, an error has occurred. Our teams have been notified
to resolve the issue as quickly as possible.
%p.fr-text--sm.fr-mb-5w
Try refreshing the page or try again a little later.
%br
If you need immediate assistance, please contact us.
%ul.fr-btns-group.fr-btns-group--inline-md
%li
= link_to("Contact Us", contact_path, class: "fr-btn fr-btn--secondary")
= render partial: "artwork"

View file

@ -0,0 +1,19 @@
%main#content{ role: "main" }
.fr-container
.fr-my-7w.fr-mt-md-12w.fr-mb-md-10w.fr-grid-row.fr-grid-row--gutters.fr-grid-row--middle.fr-grid-row--center
.fr-py-0.fr-col-12.fr-col-md-6
%h1 Erreur inattendue
%p.fr-text--sm.fr-mb-3w Erreur 500
%p.fr-text--lead.fr-mb-3w
Désolé, une erreur est survenue. Nos équipes ont été averties
pour résoudre le problème le plus rapidement possible.
%p.fr-text--sm.fr-mb-5w
Essayez de rafraîchir la page ou réessayez un peu plus tard.
%br
Si le problème persiste, merci de nous contacter.
%ul.fr-btns-group.fr-btns-group--inline-md
%li
= link_to("Contactez-nous", contact_path, class: "fr-btn fr-btn--secondary")
= render partial: "artwork"

View file

@ -699,6 +699,7 @@ Rails.application.routes.draw do
resources :release_notes, only: [:index]
get '/404', to: 'errors#not_found'
get '/500', to: 'errors#internal_server_error'
if Rails.env.test?
scope 'test/api_geo' do

File diff suppressed because one or more lines are too long

BIN
public/fonts/Marianne-Bold.woff2 Executable file

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,18 @@
module WithoutDetailedExceptions
RSpec.configure do |config|
config.include self, type: :system
end
# Snippet from https://github.com/rspec/rspec-rails/issues/2024
def without_detailed_exceptions
env_config = Rails.application.env_config
original_show_exceptions = env_config['action_dispatch.show_exceptions']
original_show_detailed_exceptions = env_config['action_dispatch.show_detailed_exceptions']
env_config['action_dispatch.show_exceptions'] = true
env_config['action_dispatch.show_detailed_exceptions'] = false
yield
ensure
env_config['action_dispatch.show_exceptions'] = original_show_exceptions
env_config['action_dispatch.show_detailed_exceptions'] = original_show_detailed_exceptions
end
end

View file

@ -0,0 +1,29 @@
describe 'Errors handling', js: false do
let(:procedure) { create(:procedure) }
scenario 'bug renders dynamic 500 page' do
procedure.revisions.destroy_all # break procedure
without_detailed_exceptions do
visit commencer_path(path: procedure.path)
end
expect(page).to have_http_status(:internal_server_error)
expect(page).to have_content('une erreur est survenue')
expect(page).to have_content('Se connecter')
expect(page).to have_link('Contactez-nous')
end
scenario 'fatal error fallback to static 500 page' do
without_detailed_exceptions do
Rails.application.env_config["action_dispatch.cookies"] = "will fail"
visit commencer_path(path: procedure.path)
ensure
Rails.application.env_config.delete("action_dispatch.cookies")
end
expect(page).to have_content('une erreur est survenue')
expect(page).not_to have_content('Se connecter')
expect(page).to have_link('Contactez-nous')
end
end