Gestion des erreurs d’email¶
Composants¶
config/packages/mailer.yamlconfigure Symfony Mailer avecMAILER_DSN.MailerServiceconstruit et envoie les emails.- Les contrôleurs et subscribers interprètent le booléen retourné.
- Monolog et
error_log()assurent la seule trace technique actuelle.
Capture des erreurs¶
Les méthodes suivantes entourent $mailer->send() avec un try/catch :
sendEmail()sendErrorNotification()sendEmailAdminAccountCreated()sendEmailToCustomer()
Seules les exceptions implémentant TransportExceptionInterface sont capturées. En cas de panne SMTP, timeout, rejet du serveur ou problème de connexion :
- un message est écrit avec
error_log(); - la méthode retourne
false; - l’opération métier appelante peut continuer.
Les erreurs de construction du message, de rendu Twig, de pièce jointe ou les erreurs PHP ne correspondant pas à TransportExceptionInterface peuvent remonter jusqu’au gestionnaire global d’exceptions.
Comportement des appels métier¶
Création d’utilisateur¶
L’utilisateur est persisté avant les emails. Si un envoi échoue, la création reste validée et le contrôleur affiche un avertissement. Le nombre de notifications administrateur réussies est comparé au nombre de destinataires.
Envoi d’une facture¶
Le PDF est généré, puis envoyé au client. Un échec retourne false et produit un message flash d’avertissement. Les notifications internes sont comptées séparément.
Alertes automatiques¶
ProductStockSubscriber et FundEmailSubscriber appellent sendEmail(). Ils n’exploitent pas toujours le booléen retourné : un échec peut donc n’être visible que dans les logs.
Gestionnaire global d’exceptions¶
ExceptionListener génère un identifiant unique, journalise l’exception et produit une réponse JSON ou HTML. La notification email d’erreur existe dans le code, mais son appel est actuellement commenté afin d’éviter une boucle d’erreur si le transport email est lui-même indisponible.
Cache, buffer et retry¶
Il n’existe pas de « cache des erreurs email » au sens d’une persistance permettant un nouvel essai :
- aucune entité de type
FailedEmail; - aucun cache Symfony dédié ;
- aucun transport Messenger pour l’email ;
- aucune stratégie de retry ;
- aucune dead-letter queue.
En production, le handler Monolog fingers_crossed conserve temporairement jusqu’à 50 enregistrements en mémoire et les publie lorsqu’un niveau error survient. Ce buffer de logs n’est pas une file d’emails et ne permet pas de rejouer un envoi.
Conséquences¶
- L’échec d’un email ne rollback généralement pas l’opération métier.
- Un redémarrage perd toute possibilité de retry applicatif.
- Le destinataire peut ne jamais recevoir le message.
error_log()fournit peu de contexte structuré et ne contient pas d’identifiant métier commun.
Évolution recommandée¶
Pour un mailing fiable :
- publier une commande email dans Symfony Messenger après validation métier ;
- utiliser un transport persistant, par exemple Doctrine, Redis ou AMQP ;
- configurer backoff, nombre maximal de tentatives et failed transport ;
- stocker un identifiant d’idempotence par type d’email et événement ;
- journaliser destinataire masqué, template, événement, tentative et erreur ;
- fournir une commande ou interface de rejeu ;
- ne jamais inclure mot de passe, JWT ou contenu sensible dans les logs.
Une transaction Doctrine ne doit pas englober l’appel SMTP. Il faut valider les données métier, committer, puis envoyer de manière asynchrone.
Diagnostic¶
Vérifier dans cet ordre :
MAILER_DSNet l’expéditeurMAILER_FROM;- connectivité DNS/TCP/TLS vers le serveur SMTP ;
- authentification et quotas du compte ;
- logs contenant
Erreur envoi email; - rendu du template et disponibilité des pièces jointes ;
- réponses de rejet, anti-spam ou limitation du provider.