---
title: "Masquage d'erreur"
type: "antipattern"
slug: "error-hiding"
url: "http://localhost:3000/fr/antipatterns/error-hiding.md"
description: "Ne pas signaler les détails d'une erreur"
---
# Masquage d'erreur

> Ne pas signaler les détails d'une erreur

En [programmation informatique](https://en.wikipedia.org/wiki/Computer%5Fprogramming "Computer programming"), le **masquage d'erreur** (ou **absorption d'erreur**) est la pratique consistant à intercepter une erreur ou une [exception](https://en.wikipedia.org/wiki/Exception%5F%28computing%29 "Exception (computing)"), puis à poursuivre sans journaliser, traiter ni signaler l'erreur aux autres parties du logiciel. Gérer les erreurs de cette manière est considéré comme une mauvaise pratique et comme un [anti-pattern](https://en.wikipedia.org/wiki/Anti-pattern "Anti-pattern") en [programmation informatique](https://en.wikipedia.org/wiki/Computer%5Fprogramming "Computer programming"). Dans les langages dotés de la [prise en charge de la gestion des exceptions](https://en.wikipedia.org/wiki/Exception%5Fhandling#Exception%5Fsupport%5Fin%5Fprogramming%5Flanguages "Exception handling"), cette pratique est appelée **absorption d'exception**.

Les erreurs et les exceptions ont plusieurs finalités :

* Aider les mainteneurs du logiciel à localiser et à comprendre les problèmes survenant lorsqu'un utilisateur exécute le logiciel, lorsqu'elles sont associées à un système de journalisation
* Fournir des informations utiles à l'utilisateur du logiciel, lorsqu'elles sont associées à des messages d'erreur explicites, à des codes d'erreur ou à des types d'erreur affichés dans une interface utilisateur, sous forme de messages de console ou de données renvoyées par une [API](https://en.wikipedia.org/wiki/API "API") (selon le type de logiciel et le type d'utilisateur)
* Indiquer que le fonctionnement normal ne peut pas se poursuivre, afin que le logiciel puisse recourir à d'autres moyens d'accomplir la tâche requise ou interrompre l'opération.

Lorsque les erreurs sont absorbées, ces finalités ne peuvent être atteintes. Les informations relatives à l'erreur sont perdues, ce qui rend très difficile la localisation des problèmes. Selon la manière dont le logiciel est implémenté, cela peut provoquer des effets de bord involontaires qui se propagent en cascade vers d'autres erreurs, déstabilisant le système. Sans information sur la cause profonde du problème, il est très difficile de comprendre ce qui ne va pas ou comment le corriger.

## Exemples

### Langages avec gestion des exceptions

Dans cet exemple en [C#](https://en.wikipedia.org/wiki/C%5FSharp%5F%28programming%5Flanguage%29 "C Sharp (programming language)"), bien que le code situé à l'intérieur du bloc _try_ lève une exception, celle-ci est interceptée par la clause _catch_ générale. L'exception a été absorbée et est considérée comme traitée, et le programme se poursuit.

try {
  throw new Exception();
} catch {
  // ne rien faire
}

Dans cet exemple en [PowerShell](https://en.wikipedia.org/wiki/PowerShell "PowerShell"), la clause _trap_ intercepte l'exception levée et l'absorbe en poursuivant l'exécution. Le message _"I should not be here"_ est affiché comme si aucune exception ne s'était produite.

&{
  trap { continue }
  throw
  write-output "I should not be here"
}

L'absorption d'exception peut aussi se produire si l'exception est traitée puis relancée sous la forme d'une exception différente, écartant l'exception d'origine et tout son contexte.

Dans cet exemple en C#, toutes les exceptions sont interceptées quel que soit leur type, et une nouvelle exception générique est levée, ne conservant que le message de l'exception d'origine. La trace de pile d'origine est perdue, de même que le type de l'exception d'origine, toute exception que l'exception d'origine encapsulait, et toute autre information capturée dans l'objet exception.

try {
    // faire quelque chose
} catch (Exception ex) {
    // éventuellement effectuer un traitement local de l'exception
    throw new Exception(ex.Message);
}

Une meilleure façon de relancer des exceptions sans perdre d'information consiste à relancer l'exception d'origine depuis la clause _catch_ :

try {
    // faire quelque chose
} catch (Exception ex) {
    // effectuer un traitement local de l'exception
    throw;
}

Une autre solution consiste à créer une nouvelle exception qui encapsule l'exception d'origine, de sorte que tout autre gestionnaire ait accès aux deux :

try {
    // faire quelque chose
} catch(Exception ex) {
    // éventuellement effectuer un traitement local de l'exception
    throw new CustomException(ex);
}

### Autres langages

En [Go](https://en.wikipedia.org/wiki/Go%5F%28programming%5Flanguage%29 "Go (programming language)"), les erreurs sont propagées en renvoyant un objet _Error_ en plus de la valeur de retour normale de la fonction. Elle peut être ignorée, comme dans cet exemple.

f, _ := "I should not be here", errors.New("")
fmt.Print(f)

Dans le cas des appels système en [C](https://en.wikipedia.org/wiki/C%5F%28programming%5Flanguage%29 "C (programming language)"), les erreurs sont signalées par une valeur de retour de l'appel égale à _NULL_, et les informations d'erreur sont stockées dans une variable globale _errno_. Ce code s'assure que le _file_ est valide avant d'y accéder, mais si _fopen_ a échoué, l'erreur est absorbée.

FILE *file = fopen("", "r");
if (file) {
  // faire quelque chose avec le fichier
}

## Causes

La cause sous-jacente la plus fréquente de l'absorption d'erreur est l'absence de bons outils et processus de journalisation pendant que le développeur construit le logiciel. Face à une erreur qui ne peut être facilement traitée, si le développeur dispose de bons outils de journalisation, consigner une erreur inattendue ne lui coûte ni temps ni effort. La journalisation de l'erreur devrait être simple (un seul appel de méthode), rapide (sans incidence sur les performances de l'application), sûre (sans lever d'erreur ni d'exception), et garantir que toutes les informations sont sauvegardées, en enregistrant le type d'erreur et toutes les données pertinentes qui y sont associées, la [trace de pile](https://en.wikipedia.org/wiki/Stack%5Ftrace "Stack trace") de l'erreur (afin que le développeur puisse identifier exactement où l'erreur s'est produite et quelles instructions y ont conduit), ainsi que l'horodatage de l'erreur.

### Gestionnaires d'exceptions temporaires

Dans les langages dotés d'[exceptions vérifiées](https://en.wikipedia.org/wiki/Checked%5Fexceptions "Checked exceptions"), toutes les exceptions levées dans une méthode doivent figurer dans la signature de cette méthode. Lors du prototypage et de l'implémentation d'un logiciel, le code change souvent, ce qui signifie que le type des exceptions susceptibles d'être levées dans une méthode change aussi souvent. Devoir ajuster la signature de la méthode chaque fois qu'un changement survient ralentit le développement et peut être frustrant ; absorber les exceptions à titre de mesure temporaire pendant d'importantes modifications de code est donc tentant. Ce code de gestion d'exceptions temporaire peut se retrouver dans la [base de code](https://en.wikipedia.org/wiki/Codebase "Codebase") livrée.

Même dans les langages sans exceptions vérifiées, il peut arriver que l'on ajoute des gestionnaires d'exceptions temporaires pendant d'importantes modifications de code afin d'accélérer le prototypage, ce qui peut conduire à l'absorption d'erreur.

### Éviter les plantages

Dans les situations où un logiciel ne doit planter sous aucun prétexte, l'absorption d'erreur est une pratique dans laquelle un programmeur peut facilement tomber. Par exemple, un [plugin](https://en.wikipedia.org/wiki/Plug-in%5F%28computing%29 "Plug-in (computing)") qui s'exécute à l'intérieur d'une autre application est censé gérer toutes les erreurs et exceptions de manière à ne pas faire planter l'application dans laquelle il est intégré. L'interception générale des erreurs et des exceptions est un schéma dans lequel il est facile de tomber lorsqu'on cherche à éviter les plantages à tout prix, et lorsqu'on combine cela avec de mauvais outils de journalisation, l'absorption d'erreur peut survenir.

### Masquer la complexité aux utilisateurs

Lorsqu'on présente des erreurs aux utilisateurs, il est important de transformer des erreurs techniques absconses en messages expliquant ce qui s'est passé et quelles actions l'utilisateur peut entreprendre, le cas échéant, pour résoudre le problème. Au cours de cette traduction des erreurs techniques en messages utiles pour l'utilisateur, des erreurs spécifiques sont souvent regroupées en erreurs plus génériques, et ce processus peut conduire à des messages utilisateur devenant si inutiles que l'utilisateur ne sait ni ce qui n'a pas fonctionné ni comment y remédier. Du point de vue de l'utilisateur, l'erreur a été absorbée.
