{# # ============================================================================ # PAGE: ERROR (Generic Fallback) # ============================================================================ # # Page d'erreur générique affichée pour tout code HTTP non géré # individuellement (hors 404, 403, 500 qui ont leurs propres templates). # # Symfony fournit automatiquement les variables: # - status_code : code HTTP (int) # - status_text : texte associé au code HTTP (string) # # ============================================================================ # COMPOSITION # ============================================================================ # # - _atoms/logo/logo-with-text.html.twig # - _atoms/icon/icon.html.twig # - _atoms/button/button.html.twig # # ============================================================================ #} {% extends 'base.html.twig' %} {% block title %}Erreur {{ status_code }} - Bubul{% endblock %} {% block meta_description %}Une erreur est survenue.{% endblock %} {# Une page d'erreur republie l'URL demandee dans canonical/og:url/twitter:url (base.html.twig). Sous /p/, cette URL PORTE LE JETON de partage : la laisser heriter du « index, follow » par defaut de base.html.twig reviendrait a inviter les moteurs a indexer un lien prive. L'en-tete X-Robots-Tag pose par PublicShareResponseListener ne couvre que le corps du dispositif ; ce bloc couvre TOUTES les URL reflechies, quelle que soit la route. #} {% block meta_robots %}noindex, nofollow{% endblock %} {% block show_sidebar %}{{ app.user ? 'true' : 'false' }}{% endblock %} {% block body %} {# ============================================================================ CONFIGURATION ============================================================================ #} {% set errorMessages = { 400: { title: 'Requête incorrecte', description: 'La requête envoyée est invalide ou mal formatée. Vérifiez les données saisies et réessayez.', icon: 'alert', accentColor: 'warning' }, 401: { title: 'Authentification requise', description: 'Vous devez être connecté pour accéder à cette page. Veuillez vous identifier.', icon: 'lock', accentColor: 'warning' }, 402: { title: 'Paiement requis', description: 'Cette fonctionnalité nécessite un abonnement actif ou des tokens supplémentaires.', icon: 'token', accentColor: 'warning' }, 405: { title: 'Méthode non autorisée', description: 'La méthode utilisée pour cette requête n\'est pas prise en charge.', icon: 'alert', accentColor: 'warning' }, 408: { title: 'Temps d\'attente dépassé', description: 'Le serveur a mis trop de temps à répondre. Veuillez réessayer.', icon: 'clock', accentColor: 'warning' }, 409: { title: 'Conflit détecté', description: 'Un conflit est survenu avec l\'état actuel de la ressource. Actualisez la page et réessayez.', icon: 'alert', accentColor: 'warning' }, 410: { title: 'Ressource supprimée', description: 'Cette ressource a été définitivement supprimée et n\'est plus disponible.', icon: 'trash', accentColor: 'error' }, 413: { title: 'Fichier trop volumineux', description: 'Le fichier envoyé dépasse la taille maximale autorisée. Réduisez sa taille et réessayez.', icon: 'upload', accentColor: 'warning' }, 415: { title: 'Format non supporté', description: 'Le format de fichier envoyé n\'est pas pris en charge. Vérifiez les formats acceptés.', icon: 'document', accentColor: 'warning' }, 422: { title: 'Données invalides', description: 'Les données envoyées ne respectent pas les règles de validation. Corrigez les erreurs et réessayez.', icon: 'alert', accentColor: 'warning' }, 429: { title: 'Trop de requêtes', description: 'Vous avez effectué trop de requêtes. Veuillez patienter quelques instants avant de réessayer.', icon: 'bolt', accentColor: 'warning' }, 502: { title: 'Passerelle incorrecte', description: 'Le serveur a reçu une réponse invalide. Nos équipes sont informées du problème.', icon: 'server', accentColor: 'error' }, 503: { title: 'Service temporairement indisponible', description: 'Notre service est en maintenance ou temporairement surchargé. Veuillez réessayer dans quelques instants.', icon: 'server', accentColor: 'warning' }, 504: { title: 'Temps de réponse dépassé', description: 'Le serveur distant n\'a pas répondu à temps. Veuillez réessayer dans quelques instants.', icon: 'clock', accentColor: 'warning' } } %} {% set config = errorMessages[status_code] ?? { title: status_text|default('Erreur inattendue'), description: 'Une erreur est survenue lors du traitement de votre demande. Veuillez réessayer ou revenir à la page d\'accueil.', icon: 'alert', accentColor: 'error' } %} {# Couleurs d'accent basées sur accentColor #} {% set accentColors = { 'primary': { 'codeBg': 'bg-gradient-to-r from-gradient-start via-gradient-middle to-gradient-end', 'iconBg': 'bg-primary/10', 'iconColor': 'primary' }, 'warning': { 'codeBg': 'bg-gradient-to-r from-gradient-warning-start via-gradient-warning-middle to-gradient-warning-end', 'iconBg': 'bg-warning/10', 'iconColor': 'warning' }, 'error': { 'codeBg': 'bg-gradient-to-r from-gradient-error-start via-gradient-error-middle to-gradient-error-end', 'iconBg': 'bg-error/10', 'iconColor': 'error' } } %} {% set accent = accentColors[config.accentColor] ?? accentColors['error'] %} {# ============================================================================ HTML OUTPUT ============================================================================ #}
{# Logo (non-authenticated users only) #} {% if not app.user %}
{% include '_atoms/logo/logo-with-text.html.twig' with { size: 'lg', showBadge: false } only %}
{% endif %} {# Card #}
{# Error code in primary blue #}
{{ status_code }}
{# Title #}

{{ config.title }}

{# Description #}

{{ config.description }}

{# Actions #}
{% if app.user %} {% include '_atoms/button/button.html.twig' with { label: 'Retour au tableau de bord', href: path('app_dashboard'), variant: 'primary', size: 'lg', icon: 'home-smile', iconPosition: 'left', width: 'full' } only %} {% include '_atoms/button/button.html.twig' with { label: 'Page précédente', href: 'javascript:history.back()', variant: 'ghost', size: 'md', icon: 'arrow-left', iconPosition: 'left', width: 'full' } only %} {% else %} {% include '_atoms/button/button.html.twig' with { label: 'Retour à l\'accueil', href: path('app_landing'), variant: 'primary', size: 'lg', icon: 'home', iconPosition: 'left', width: 'full' } only %} {% endif %}
{# Error code footer #}

Erreur {{ status_code }}{% if status_text %} · {{ status_text }}{% endif %}

{% endblock %}