devstory

Tutoriel de gestion des erreurs JavaScript

  1. Qu'est- ce que Error?
  2. Le traitement de l'erreur via try-catch
  3. Le bloc try-catch-finally
  4. Built-in Errors
  5. Jeter Error
  6. Les property de Error
  7. Relancer erreur (Re-throw Error)
  8. Des exceptions lors de la capture des erreurs

1. Qu'est- ce que Error?

Tout d'abord, examinons un exemple dans lequel j'appelle la méthode d'un objet, mais cet objet n'a pas cette méthode et l'erreur se produit.
hello-error-example.js
console.log("Three");

let myObj = {};

console.log("Two");

console.log("One");

// L'objet myObj n'a pas de méthode showMe().
// Mais nous appelons la méthode showMe().
// Et l'erreur se produit ici.
myObj.showMe(); // ==> Error!!!!!!!!! 

// L'extrait de code ci-dessous ne sera pas exécuté.
console.log("Let's go!");
Le résultat de l'exécution de l'exemple:
Vous pouvez voir la notification sur l'écran de la Console. La notification d'erreur est très claire, y compris les informations de la ligne de code.
Veuillez observer le flux du programme via l'illustration ci-dessous.
  • Le programme exécute complètement et normalement dans les étapes (1), (2), (3), (4)
  • Dans l'étape (5) une erreur se produit lorsque vous essayez d'appeler une méthode d'objet alors que cet objet n'existe pas dans la méthode.
  • Le code dans l'étape (6) ne sera pas exécuté.

2. Le traitement de l'erreur via try-catch

Des erreurs peuvent survenir lors de l'exécution (runtime) du programme. cela peut être une erreur inattendue. Utilisez try-catch vous permet de détecter et de gérer les erreurs lorsqu'elles se produisent.
Revenons à l'exemple ci-dessus, nous ajoutons try-catch pour détecter et gérer des erreurs.
hello-catch-example.js
console.log("Three");

let myObj = {};

console.log("Two");

console.log("One");

try {
    // L'objet myObj ne contient pas la méthode showMe().
    // Mais nous appelons la méthode showMe().
    // Et l'erreur se produit ici.
    myObj.showMe(); // ==> Error!

    // Ce code sera ignoré.
    console.log("!!!"); 
} catch (e) {
    console.log("Catched error: " + e);
    console.log("OK continue...");
} 
console.log("Let's go!");
Et les résultats de l'exécution de l'exemple :
Three
Two
One
Catched error: TypeError: myObj.showMe is not a function
OK continue...
Let's go!
L'illustration ci-dessous explique le flux (flow) du programme :
  • Les étapes (1)-(4) sont complètement normales.
  • Une exception se produit à l'étape (5), lorsque vous essayez d'appeler une méthode d'un objet, alors que cet objet n'a pas été compris dans cette méthode.
  • Immédiatement il saute pour exécuter la commande dans le bloc catch, l'étape (6) est ignorée.
  • Les étapes (7), (8) seront exécutées.
  • L'étape (9) sera exécutée.

3. Le bloc try-catch-finally

Nous nous sommes habitués à attraper l'erreur via le bloc try-catch. Le traitement des error complète est try-catch-finally. Le bloc finally est toujours exécuté, quel que soit l'error se produisant ou non dans le bloc try.
try {  
   // Faire quelque chose ici.
} catch (e ) { 
   // Faire quelque chose ici.
} finally  {
   // Le bloc finally est toujours exécuté.
   // Faire quelque chose ici.
}
Exemple :
try-catch-finally-example.js
function getGreeting(language) {
    try {
        console.log("Code in try block (*)"); 
        // Appeler la méthode greeting() de l'objet 'language'.
        // Une exception peut être lancée ici si cet objet ne contient pas la méthode greeting().
        let v = language.greeting(); 
        console.log("Code in try block (**)"); 
        return v; 
    } catch (e) { 
        console.log("Code in catch block. Something Error: " + e); 
    } finally {
        // Le bloc 'catch' sera exécuté.
        console.log("Code in finally block");
    } 
    return " !! ";
} 
// ----------------------- TEST --------------------------------- 
// Test 1:
console.log("----- Call getGreeting(null) -----"); 
let v1 = getGreeting(null);
console.log("Greeting: " + v1);  
// Test 2:
console.log("------ Call getGreeting(language) ------"); 
let language = new Object(); 
language.greeting = function() {
    return "Hello Everybody";
} 
let v2 = getGreeting(language); 
console.log("Greeting: " + v2);
Exécution de l'exemple:
----- Call getGreeting(null) -----
Code in try block (*)
Code in catch block. Something Error: TypeError: Cannot read property 'greeting' of null
Code in finally block
Greeting:  !!
----- Call getGreeting(language) -----
Code in try block (*)
Code in try block (**)
Code in finally block
Greeting: Hello Everybody
L'illustration suivante représente le flux du programme si une erreur se produit dans le bloc try, le bloc finally est toujours exécuté.
La figure suivante montre le flux du programme lorsqu'aucune erreur ne survient dans le bloc try. Dans ce cas, le bloc finally sera exécuté immédiatement avant l'exécution de la commande de return du bloc try.

4. Built-in Errors

ECMAScript contient plusieurs classes disponibles pour représenter une erreur. Ci-dessous, leur hiérarchie (hierarchy).
RangeError
Une RangeError est lancée au cas où vous utiliser un numéro de l'extérieur du champ admissible.
error-RangeError-example.js
let num = 1;
try {

  // A number cannot have 500 significant digits
  num.toPrecision(500); // ==> RangeError!!
 
}
catch(err) {
  console.log(err.name);
  console.log(err);
}
ReferenceError
Une ReferenceError sera lancée (throw) si vous utilisez une variable qui n'a pas été déclarée.
error-ReferenceError-example.js
var x;
try {
  x = y + 1;   // y cannot be referenced (used)
}
catch(err) {
   console.log("Error Name: "+ err.name);
   console.log(err);
}
SyntaxError
Une SyntaxError sera lancée (throw) si vous essayez d'évaluer (evaluate) un extrait de code dont la syntaxe n'est pas correcte.
error-SyntaxError-example.js
try {
  let x;
  eval(" x  = 'Hello  ");   // Missing ' will produce an error
}
catch(err) {
  console.log("Error Name: " + err.name);
  console.log(err);
}
TypeError
Une TypeError sera lancée (throw) si vous utilisez une valeur qui n'est pas de type prévu. Par exemple, une erreur se produit lorsque vous appelez une méthode d'un objet, alors que cet objet ne contient pas cette méthode la.
error-TypeError-example.js
var num = 1;
try {
  num.toUpperCase(); // Number has no method toUpperCase()
}
catch(err) {
  console.log("Error Name: " + err.name);
  console.log(err);
}
URIError
Une URIError sera jetée (throw) si vous utilisez des caractères illégales dans une fonction URI :
error-URIError-example.js
try {
  decodeURI("%%%");   // You cannot URI decode percent signs
}
catch(err) {
  console.log("Error Name: " + err.name);
  console.log(err);
}

5. Jeter Error

ECMAScript vous permet de jeter (throw) n'importe quoi lors de l'exécution du programme, le programme considérera qu'une erreur vient de se produire.
throw-any-example.js
console.log(" -------- Test throw any object ------------");
try {
   let myObj = {};
   throw myObj;
} catch(e)  {
   console.log("Catch error: ");
   console.log(e);
}
console.log(" -------- Test throw a Symbol ------------");
try {
   let mySymbol = Symbol();
   throw mySymbol;
} catch(e)  {
   console.log("Catch error: ");
   console.log(e);
}
console.log(" -------- Test throw a Number ------------");
try {
   let myNumber = 100;
   throw myNumber;
} catch(e)  {
   console.log("Catch error: ");
   console.log(e);
}
console.log(" -------- Test throw a String ------------");
try {
   let myString = "Some error";
   throw myString;
} catch(e)  {
   console.log("Catched error: ");
   console.log(e);
}
Output:
-------- Test throw any object ------------
Catch errorr:
{}
 -------- Test throw a Symbol ------------
Catch error:
Symbol()
 -------- Test throw a Number ------------
Catch error:
100
 -------- Test throw a String ------------
Catched error:
Some error
Normalement vous allez utiliser une classe Error pour créer un objet erroné. Les classes telles que SyntaxError, InternalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError peuvent être également utilisées dans un contexte approprié.
Un objet d'erreur est créé via la classe Error (ou ses classes dérivées). Lors de son lancement (throw), il contiendra des informations importantes telles que le fichier sur lequel l'erreur se produit, son emplacement et les informations qui vous permettent de détecter les erreurs.
throw-error-example.js
console.log("Three");

// Create an Error
let myError = new Error("Something error!");
console.log("Two");
// Throw it!
throw myError;
console.log("One");
Dans le cas simple, vous pouvez lancer n'importe quel objet, pas l'objet de la classe Error (ou de ses sous classes). Toutefois, lors de la capture de ces types d’erreurs, vous ne disposerez pas des informations telles que le fichier de l’erreur, l’emplacement de l’erreur, etc.
throw-string-error-example.js
console.log("Three");
try {
  console.log("Two");
  // Throw a String!
  throw "Some error!!";
} catch(e)  {
   console.log("typeof e = " + (typeof e));
   // Log the error
   console.log(e); // Some error!!
}
console.log("One");
Output:
Three
Two
typeof e = string
Some error!!
One
En ECMAScript, chaque bloc try a un bloc cache correspondant. Mais dans le bloc try il y a plusieurs types d'erreur, dans ce cas, il vous faut vérifier la capture d'erreur dans le bloc catch afin de proposer des traitements appropriés de chaque type d'erreur.
catch-complex-example.js
let err = new Error("My Error");
let rangeErr = new RangeError();
let evalErr = new EvalError("My Eval Error");

// A random value in [0.. 9]
let randomValue = Math.floor(Math.random() * 10);

// [0,1,2,3]
let random0123 = randomValue % 4;
console.log("random0123 = " + random0123);
try {
   if(random0123 == 0) {
      throw err;
   } else if(random0123 == 1){
      throw rangeErr;
   } else if(random0123 == 2)  {
      throw evalErr;
   } else if(random0123 == 3)  {
      throw "A String Error";
   }
} catch(e)  {
   console.log("typeof e = " + (typeof e));// 'object' or 'string'
   if(e instanceof RangeError) {
      console.log("--> RangeError!!");
   } else if(e instanceof EvalError) {
      console.log("--> EvalError!!");
   } else if(e instanceof Error) {
      console.log("--> Error!!");
   } else if (typeof e == "string"){
      console.log("--> String Error!!");
   } else  {
      console.log("--> Error!!");
   }
   console.log(e);
}

6. Les property de Error

En ECMAScript, l'erreur que vous pouvez attraper est "Error object" ou quel que soit un type d'erreur. Si elle est "Error object" vous obtiendrez les informations importantes telles que le nom du fichier d’erreur, la position de l’erreur, Stack Trace, ...
Il y a quelques property importantes de la classes Error :
  • name: Nom de l'erreur.
  • message: Contenu de l'erreur.
  • stack (Readonly): est une chaine contenant des informations qui vous permet de détecter la position d'erreur.
error-properties-example.js
// Create an Error
let myError = new Error();

myError.name = "MyError";
myError.message = "My Error String"; 
try {
  throw myError; 
} catch(err)  {
  console.log("Error Name: " + err.name);
  console.log("Error Message: " + err.message);
  console.log("Type of err.stack: " + (typeof err.stack));
  console.log("--- Stack Trace: ---");  
  console.log(err.stack);
}

7. Relancer erreur (Re-throw Error)

Lors du traitement de l'exception, vous pouvez attraper cette exception et la gérer ou vous pouvez la relancer (rethrow).
rethrow-example.js
function checkScore(score) {
    if (score < 0 || score > 100) {
        throw "Invalid Score " + score;
    }
} 
function checkPlayer(name, score) { 
    try { 
        checkScore(score)
    } catch (e) {
        // Faire quelque chose avec exception
        console.log("Something invalid with player: " + name + " >> " + e); 
        // Puis relancer cette exception.
        throw e;
    } 
    console.log("OK Player " + name + " has score: " + score );
}  
// --------------- TEST -------------- 
checkPlayer("Tom", 90); 
checkPlayer("Jerry", -10);
Par exemple, attrapez une exception et jettez (rethrow) une autre exception.
rethrow-example2.js
function checkScore(score) {
    if (score < 0 || score > 100) {
        throw "Invalid Score " + score;
    }
} 
function checkPlayer(name, score) { 
    try { 
        checkScore(score)
    } catch (e) {
        // Faire quelque chose avec exception
        console.log("Something invalid with player: " + name + " >> " + e); 
        // Puis lancer une autre exception
        throw ("Score " + score +" invalid for player " + name);
    } 
    console.log("OK Player " + name + " has score: " + score );
}  
// --------------- TEST -------------- 
checkPlayer("Tom", 90); 
checkPlayer("Jerry", -10);

8. Des exceptions lors de la capture des erreurs

En ECMAScript il y a les cas que vous pensez qu'il y aura des erreur survenant mais cela ne se produit pas. Par exemple, la division par 0 ne posera pas une erreur, le résultat renvoie Infinity ou -Infinity.
ex-Infinity-example.js
console.log( typeof Infinity ); // number

let a = 1 / 0;
console.log(a); // Infinity

let b = -1 / 0;
console.log(b); // -Infinity
Diviser une valeur à part un nombre par un nombre, le résultat est NaN (Not a Number).
ex-NaN-example.js
console.log( typeof NaN ); // number
console.log( isNaN(1) ); // false
console.log( isNaN( NaN ) ); // true

let a = "A String" / 2;
console.log(a); // NaN

let obj = {};
let b = obj / 2;
console.log(b); // NaN
Vous pouvez accéder à un élément quel que soit index d'un tableau (Array) sans provoquer d'erreur.
ex-array-index-example.js
let myArray = [1, 100, 20];

console.log( myArray[1]); // 100
console.log( myArray[10] ); // undefined
console.log( myArray[-10] ); // undefined

Tutoriels de programmation ECMAScript, Javascript

Show More