HOWTO · JavaScript
Try sans Catch en JavaScript
Dans l'article d'aujourd'hui, nous allons découvrir les instructions try sans implémenter catch en JavaScript.
Sur cette page
Oui — une instruction try JavaScript peut omettre catch, à condition qu’une clause finally soit présente. Ce tutoriel explique quand try sans catch est valide, ce qu’il advient d’une erreur levée et quand cette forme est le bon outil.
Fonctionnement de try sans catch en JavaScript
L’instruction try de JavaScript encadre du code susceptible de lever une erreur ; elle est valide partout où une instruction est autorisée : au niveau supérieur d’un script, dans une fonction ou imbriquée dans un autre try. En revanche, elle ne peut pas apparaître seule : un bloc try doit être suivi d’une clause catch, d’une clause finally ou des deux ; un try sans aucune des deux est donc une erreur de syntaxe. Les accolades {} sont toujours obligatoires, même pour une seule instruction.
Syntaxe :
Le squelette ci-dessous reste en anglais ; ses commentaires indiquent le rôle de chaque bloc.
try {
// try_statements: code that may throw
} catch (exception_var) {
// catch_statements: handle the thrown value
} finally {
// finally_statements: always run afterward
}
try_statementssont les instructions à exécuter.catch_statementssont les instructions exécutées lorsqu’une valeur est levée dans le bloctry.exception_varest un identifiant optionnel qui contient la valeur levée pour le bloccatchassocié.finally_statementss’exécutent une fois l’instructiontryterminée, qu’une valeur ait été levée ou interceptée ou non.
catch n’étant optionnel que lorsque finally est présent (et inversement), la grammaire autorise exactement trois combinaisons :
try...catchtry...finallytry...catch...finally
Lorsqu’un bloc catch est présent et qu’une instruction à l’intérieur du bloc try (ou une fonction qu’elle appelle) lève une valeur, le contrôle passe immédiatement à catch ; lorsque rien n’est levé, catch est entièrement ignoré. Le bloc finally s’exécute toujours après la fin des blocs try et catch, qu’une valeur ait été levée ou non et que catch l’ait gérée ou non.
Sans clause catch, finally s’exécute quand même en premier, puis la valeur levée continue de se propager vers l’appelant. Cela vaut aussi pour l’imbrication : les instructions try peuvent être imbriquées et, lorsqu’une instruction try interne n’a pas de catch, c’est le bloc catch d’un try englobant qui gère l’erreur.
Pour la grammaire complète, consultez la documentation MDN de try...catch.
Exemple : try...finally sans catch
L’extrait ci-dessous place un try...finally dépourvu de catch à l’intérieur d’un try...catch externe, afin d’observer l’exécution du bloc finally et de voir où aboutit la valeur levée. 0 / 0 s’évalue à NaN, donc throw new Error(0 / 0) lève une Error dont le message est NaN.
Exécutez cet exemple :
Le code et sa sortie console restent en anglais ; l’exemple affiche Executing try block, Final Call puis Outer catch received: NaN.
try {
try {
console.log('Executing try block')
throw new Error(0 / 0)
} finally {
console.log('Final Call')
}
} catch (error) {
console.log('Outer catch received: ' + error.message)
}
Executing try block
Final Call
Outer catch received: NaN
Le try interne affiche sa ligne de journal, puis lève l’erreur. Comme il n’a pas de catch, le contrôle passe directement à finally, qui affiche Final Call. Ce n’est qu’après la fin de finally que l’Error continue de se propager : le catch externe la reçoit et affiche son message NaN. Sans ce catch englobant, la même erreur parviendrait à l’appelant ou, au niveau supérieur, apparaîtrait comme une erreur non interceptée après l’affichage de Final Call.
Quand utiliser try sans catch
Choisissez try...finally lorsqu’un bloc a besoin d’un nettoyage garanti mais que l’erreur elle-même revient à l’appelant. Les tâches typiques de finally incluent la libération d’une ressource, la fermeture d’une connexion ou d’un descripteur de fichier, la restauration d’un état partagé comme un bouton réactivé ou un indicateur réinitialisé, et l’arrêt d’un minuteur — un travail qui doit avoir lieu que le bloc try se termine normalement ou lève une erreur.
Cette forme est le bon choix lorsque le code n’a rien de significatif à ajouter à l’erreur : la lever à nouveau à l’identique ne fait qu’ajouter du bruit, tandis qu’un bloc catch vide avale silencieusement chaque échec, si bien que les bogues refont surface loin de leur cause. try...finally conserve la garantie de nettoyage tout en laissant l’appelant voir et gérer l’erreur. Si la fonction a réellement besoin d’inspecter la valeur levée, de la journaliser ou de récupérer après erreur, ajoutez plutôt une véritable clause catch.
Limites et pièges de try sans catch
finallyne gère ni ne supprime jamais l’erreur. Une foisfinallyterminé, une valeur levée non gérée continue de se propager vers l’appelant ; au niveau supérieur, elle met fin au script ou signale une erreur non interceptée.- Vous ne pouvez pas observer la valeur levée. Sans
catch, la construction n’a pas accès à ce qui a été levé : elle ne peut donc ni consigner le message ni exécuter un traitement différent selon le type d’erreur. - Le flux de contrôle à l’intérieur de
finallyl’emporte sur tout ce qui était en attente. Unreturnou unthrowdansfinallyécarte une valeur encore en cours de propagation — y compris une erreur levée, qui disparaît alors silencieusement — donc limitezfinallyà un simple nettoyage qui n’exécute nireturnnithrow. - Les instructions situées après un
try...finallyne s’exécutent que si rien n’a été levé, etfinallylui-même ne doit pas dépendre du succès du bloctry, puisqu’il s’exécute aussi sur le chemin d’échec.