Bonnes pratiques relatives à la gestion des exceptions
Si une exception n’est pas écrite dans le fichier exception.log
avec le modèle d’exception comme contexte, elle n’est pas reconnue et analysée correctement dans New Relic ou dans un autre stockage de journal compatible avec le format PSR-3. La journalisation d’une partie seulement de l’exception (ou la journalisation dans un fichier incorrect) entraîne des bogues en production lorsque les exceptions sont négligées.
Correction de la gestion des exceptions
La liste de contrôle suivante fournit des exemples pour démontrer la gestion correcte des exceptions.
Écriture dans le journal des exceptions
Écrivez dans le journal des exceptions à l’aide du modèle suivant, indépendamment des autres actions, sauf s’il y a une raison irréfutable de ne pas le faire.
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->critical($e);
}
Cette approche enregistre automatiquement le $e->getMessage
dans le message du journal et l’objet $e
dans le contexte, en suivant la norme contextuelle PSR-3. Cette opération est effectuée dans \Magento\Framework\Logger\Monolog::addRecord
.
Signaux muets
Mutez les signaux en ne consignant pas les exceptions qui font partie du flux d’opérations prévu. Aucune action de suivi n’est nécessaire lorsque l’exception est rencontrée. Il n’est donc pas nécessaire de la consigner et de l’analyser lorsqu’elle se produit. Ajoutez un commentaire indiquant la raison de l’arrêt des signaux et le caractère intentionnel de ce dernier. Combinez avec phpcs:ignore
.
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) { // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch
// Product already removed
}
Exceptions de rétrogradation
Réduisez les exceptions en suivant la norme contextuelle PSR-3.
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->debug($e->getMessage(), ['exception' => $e]);
}
La journalisation est toujours la première
La journalisation est une bonne pratique qui s’affiche toujours en premier dans le code afin d’éviter les cas où une autre exception ou erreur fatale est générée avant d’écrire dans le journal.
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->critical($e);
$this->alternativeProcedure();
}
Enregistrer les messages et toute la trace de l'exception
Consignez les messages et la trace complète des exceptions en suivant la norme contextuelle PSR-3.
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->critical($e->getMessage(), ['exception' => $e, 'trace' => $e->getTrace()]);
}
Gestion des exceptions incorrecte
Les exemples suivants montrent une gestion incorrecte des exceptions.
Logique avant journalisation
La logique avant la journalisation peut entraîner une autre exception ou une erreur fatale, qui empêche l’enregistrement de l’exception et doit être remplacée par exemple correct.
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) {
$this->alternativeProcedure();
$this->logger->critical($e);
}
vide catch
Les blocs catch
vides peuvent être un signe d’arrêt involontaire et doivent être remplacés par l’ exemple correct.
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) {
}
Double localisation
Si l’exception localisée capturée n’est pas encore traduite, résolvez le problème à l’emplacement où l’exception est générée la première fois.
try {
$this->productRepository->getById($sku);
} catch (LocalizedException $e) {
throw new LocalizedException(__($e->getMessage()));
}
Messages du journal et trace dans différents fichiers journaux
Le code suivant consigne incorrectement la trace de la pile pour une exception en tant que chaîne à un fichier journal.
try {
$this->productRepository->getById($sku);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
$this->logger->debug($e->getTraceAsString());
}
Cette approche introduit des sauts de ligne dans le message, qui n’est pas conforme au PSR-3. L’exception, y compris la trace de la pile, doit faire partie du contexte du message pour s’assurer qu’il est enregistré correctement avec le message dans New Relic ou dans un autre stockage de journal compatible avec le format PSR-3.
Réparez ce problème en remplaçant le code en suivant les exemples corrects présentés dans la section Écrire dans le journal des exceptions ou Rétrograder les exceptions.
Rétrogradation des exceptions sans contexte
L’exception est dégradée en erreur, ce qui ne permet pas de transmettre un objet, mais seulement une chaîne, d’où l’ getMessage()
. Cela entraîne la perte de la trace et doit être remplacé par les exemples corrects présentés dans la section Écrire au journal des exceptions ou Rétrograder les exceptions.
try {
$this->productRepository->getById($sku);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
Consigne uniquement le message dans le journal des exceptions
Au lieu de transmettre l’objet $e
, seul $e->getMessage()
est transmis. Cela entraîne la perte de la trace et doit être remplacé par les exemples corrects affichés Écrire dans le journal des exceptions ou Rétrograder les exceptions.
try {
$this->productRepository->getById($sku);
} catch (\Exception $e) {
$this->logger->critical($e->getMessage());
}
Absente // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch
Si vous omettez la ligne phpcs:ignore
, un avertissement s’affiche dans le PHPCS et vous ne devriez pas transmettre votre CI. Ceci doit être remplacé par l’exemple correct illustré dans Signaux muets.
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) {
// Product already removed
}