You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/10-error-handling/2-custom-errors/article.md
+50-50Lines changed: 50 additions & 50 deletions
Original file line number
Diff line number
Diff line change
@@ -1,42 +1,42 @@
1
-
# Custom errors, extending Error
1
+
# Les erreurs personnalisées, Étendre Error
2
2
3
-
When we develop something, we often need our own error classes to reflect specific things that may go wrong in our tasks. For errors in network operations we may need `HttpError`, for database operations `DbError`, for searching operations `NotFoundError` and so on.
3
+
Lorsque nous développons quelque chose, nous avons souvent besoin de nos propres classes d'erreur pour refléter des problèmes spécifiques qui peuvent mal tourner dans nos tâches. Pour les erreurs dans les opérations réseau, nous aurons peut-être besoin de `HttpError`, pour les opérations de base de données `DbError`, pour les opérations de recherche `NotFoundError`, etc.
4
4
5
-
Our errors should support basic error properties like `message`, `name`and, preferably, `stack`. But they also may have other properties of their own, e.g. `HttpError`objects may have `statusCode`property with a value like`404`or`403`or`500`.
5
+
Nos erreurs devraient prendre en charge des propriétés d'erreur de base telles que `message`, `name`et, de préférence, `stack`. Mais ils peuvent aussi avoir d’autres propriétés propres, par exemple Les objets `HttpError`peuvent avoir une propriété `statusCode`avec une valeur telle que`404`ou`403`ou`500`.
6
6
7
-
JavaScript allows to use `throw`with any argument, so technically our custom error classes don't need to inherit from `Error`. But if we inherit, then it becomes possible to use `obj instanceof Error`to identify error objects. So it's better to inherit from it.
7
+
JavaScript permet d'utiliser `throw`avec n'importe quel argument. Par conséquent, techniquement, nos classes d'erreur personnalisées n'ont pas besoin d'hériter de `Error`. Mais si nous héritons, il devient alors possible d'utiliser `obj instanceof Error`pour identifier les objets d'erreur. Il vaut donc mieux en hériter.
8
8
9
-
As the application grows, our own errors naturally form a hierarchy, for instance`HttpTimeoutError`may inherit from`HttpError`, and so on.
9
+
Au fur et à mesure que l'application grandit, nos propres erreurs forment naturellement une hiérarchie. Par exemple,`HttpTimeoutError`peut hériter de`HttpError`, etc.
10
10
11
-
## Extending Error
11
+
## Étendre Error
12
12
13
-
As an example, let's consider a function `readUser(json)`that should read JSON with user data.
13
+
A titre d'exemple, considérons une fonction `readUser(json)`qui devrait lire JSON avec des données utilisateur.
14
14
15
-
Here's an example of how a valid `json`may look:
15
+
Voici un exemple de l'apparence d'un `json`valide:
16
16
```js
17
17
let json =`{ "name": "John", "age": 30 }`;
18
18
```
19
19
20
-
Internally, we'll use`JSON.parse`. If it receives malformed `json`, then it throws `SyntaxError`. But even if`json`is syntactically correct, that doesn't mean that it's a valid user, right? It may miss the necessary data. For instance, it may not have `name`and`age`properties that are essential for our users.
20
+
En interne, nous utiliserons`JSON.parse`. S'il reçoit un `json` malformé, il renvoie`SyntaxError`. Mais même si`json`est syntaxiquement correct, cela ne signifie pas que c'est un utilisateur valide, non? Il peut manquer les données nécessaires. Par exemple, il peut ne pas avoir les propriétés `name`et`age`qui sont essentielles pour nos utilisateurs.
21
21
22
-
Our function`readUser(json)`will not only read JSON, but check ("validate") the data. If there are no required fields, or the format is wrong, then that's an error. And that's not a `SyntaxError`, because the data is syntactically correct, but another kind of error. We'll call it `ValidationError`and create a class for it. An error of that kind should also carry the information about the offending field.
22
+
Notre fonction`readUser(json)`va non seulement lire JSON, mais aussi vérifier ("valider") les données. S'il n'y a pas de champs obligatoires ou si le format est incorrect, c'est une erreur. Et ce n’est pas une `SyntaxError`, car les données sont syntaxiquement correctes, mais un autre type d’erreur. Nous l'appellerons `ValidationError`et créerons une classe pour cela. Une erreur de ce type devrait également comporter des informations sur le champ fautif.
23
23
24
-
Our `ValidationError`class should inherit from the built-in `Error`class.
24
+
Notre classe `ValidationError`devrait hériter de la classe `Error`intégrée.
25
25
26
-
That class is built-in, here's it approximate code, for us to understand what we're extending:
26
+
Cette classe est intégrée, voici le code approximatif, pour que nous comprenions ce que nous étendons:
27
27
28
28
```js
29
-
//The "pseudocode" for the built-in Error class defined by JavaScript itself
29
+
//Le "pseudocode" pour la classe d'erreur intégrée définie par JavaScript lui-même
30
30
classError {
31
31
constructor(message) {
32
32
this.message= message;
33
-
this.name="Error"; // (different names for different built-in error classes)
34
-
this.stack=<call stack>; // non-standard, but most environments support it
33
+
this.name="Error"; // (noms différents pour différentes classes d'erreur intégrées)
34
+
this.stack=<call stack>; // nonstandard, mais la plupart des environnements le supportent
35
35
}
36
36
}
37
37
```
38
38
39
-
Now let's inherit`ValidationError`from it and try it in action:
39
+
Maintenant, héritons de`ValidationError`et mettons-le en action:
40
40
41
41
```js run untrusted
42
42
*!*
@@ -57,15 +57,15 @@ try {
57
57
} catch(err) {
58
58
alert(err.message); // Whoops!
59
59
alert(err.name); // ValidationError
60
-
alert(err.stack); //a list of nested calls with line numbers for each
60
+
alert(err.stack); //une liste des appels imbriqués avec des numéros de ligne pour chaque
61
61
}
62
62
```
63
63
64
-
Please note: in the line`(1)` we call the parent constructor. JavaScript requires us to call`super`in the child constructor, so that's obligatory. The parent constructor sets the`message` property.
64
+
Remarque: à la ligne`(1)`, nous appelons le constructeur parent. JavaScript exige que nous appelions`super`dans le constructeur de l'enfant, donc c'est obligatoire. Le constructeur parent définit la propriété`message`.
65
65
66
-
The parent constructor also sets the`name`property to `"Error"`, so in the line`(2)`we reset it to the right value.
66
+
Le constructeur parent définit également la propriété`name`sur `"Error"`, donc à la ligne`(2)`nous la réinitialisons à la valeur correcte.
67
67
68
-
Let's try to use it in`readUser(json)`:
68
+
Essayons de l'utiliser dans`readUser(json)`:
69
69
70
70
```js run
71
71
classValidationErrorextendsError {
@@ -89,7 +89,7 @@ function readUser(json) {
89
89
return user;
90
90
}
91
91
92
-
//Working example with try..catch
92
+
//un example avec try..catch
93
93
94
94
try {
95
95
let user =readUser('{ "age": 25 }');
@@ -101,31 +101,31 @@ try {
101
101
} elseif (err instanceofSyntaxError) { // (*)
102
102
alert("JSON Syntax Error: "+err.message);
103
103
} else {
104
-
throw err; //unknown error, rethrow it (**)
104
+
throw err; //erreur inconnue, propager le (**)
105
105
}
106
106
}
107
107
```
108
108
109
-
The `try..catch`block in the code above handles both our `ValidationError`and the built-in `SyntaxError`from`JSON.parse`.
109
+
Le bloc `try..catch`dans le code ci-dessus gère à la fois notre `ValidationError`et le `SyntaxError`intégré de`JSON.parse`.
110
110
111
-
Please take a look at how we use `instanceof`to check for the specific error type in the line`(*)`.
111
+
Veuillez regarder comment nous utilisons `instanceof`pour vérifier le type d'erreur spécifique à la ligne`(*)`.
112
112
113
-
We could also look at `err.name`, like this:
113
+
Nous pourrions aussi regarder `err.name`, comme ceci:
114
114
115
115
```js
116
116
// ...
117
-
//instead of (err instanceof SyntaxError)
117
+
//au lieu de (err instanceof SyntaxError)
118
118
} elseif (err.name=="SyntaxError") { // (*)
119
119
// ...
120
120
```
121
121
122
-
The `instanceof`version is much better, because in the future we are going to extend `ValidationError`, make subtypes of it, like`PropertyRequiredError`. And`instanceof` check will continue to work for new inheriting classes. So that's future-proof.
122
+
La version `instanceof`est bien meilleure, car dans le futur nous allons étendre `ValidationError`, en créer des sous-types, comme`PropertyRequiredError`. Et`instanceof` check continuera à fonctionner pour les nouvelles classes héritées. Donc, c'est à l'épreuve du futur.
123
123
124
-
Also it's important that if`catch`meets an unknown error, then it rethrows it in the line`(**)`. The `catch`block only knows how to handle validation and syntax errors, other kinds (due to a typo in the code or other unknown ones) should fall through.
124
+
De plus, il est important que si`catch`rencontre une erreur inconnue, il la propage, comme à la ligne`(**)`. Le bloc `catch`ne sait que gérer les erreurs de validation et de syntaxe, d'autres types (dus à une faute de frappe dans le code ou à d'autres inconnus) devraient "tomber".
125
125
126
-
## Further inheritance
126
+
## Héritage complémentaire
127
127
128
-
The `ValidationError`class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for `age`). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.
128
+
La classe `ValidationError`est très générique. Beaucoup de choses peuvent mal se passer. La propriété peut être absente ou dans un format incorrect (comme une valeur de chaîne pour `age`). Faisons une classe plus concrète `PropertyRequiredError`, exactement pour les propriétés absentes. Il contiendra des informations supplémentaires sur la propriété qui manque.
129
129
130
130
```js run
131
131
classValidationErrorextendsError {
@@ -159,7 +159,7 @@ function readUser(json) {
159
159
return user;
160
160
}
161
161
162
-
//Working example with try..catch
162
+
// example avec try..catch
163
163
164
164
try {
165
165
let user =readUser('{ "age": 25 }');
@@ -173,18 +173,18 @@ try {
173
173
} elseif (err instanceofSyntaxError) {
174
174
alert("JSON Syntax Error: "+err.message);
175
175
} else {
176
-
throw err; //unknown error, rethrow it
176
+
throw err; //erreur inconnue, propager le
177
177
}
178
178
}
179
179
```
180
180
181
-
The new class`PropertyRequiredError`is easy to use: we only need to pass the property name: `newPropertyRequiredError(property)`. The human-readable `message`is generated by the constructor.
181
+
La nouvelle classe`PropertyRequiredError`est facile à utiliser: il suffit de passer le nom de la propriété: `newPropertyRequiredError(property)`. Le `message`est généré par le constructeur.
182
182
183
-
Please note that`this.name`in `PropertyRequiredError`constructor is again assigned manually. That may become a bit tedious -- to assign `this.name=<classname>`in every custom error class. We can avoid it by making our own "basic error" class that assigns `this.name=this.constructor.name`. And then inherit all ours custom errors from it.
183
+
Veuillez noter que`this.name`dans le constructeur `PropertyRequiredError`est à nouveau attribué manuellement. Cela peut devenir un peu fastidieux - assigner `this.name=<classname>`dans chaque classe d'erreur personnalisée. Nous pouvons l'éviter en créant notre propre classe "d'erreur de base" qui assigne `this.name=this.constructor.name`. Et puis hériter de toutes nos erreurs personnalisées.
184
184
185
-
Let's call it`MyError`.
185
+
Appelons cela`MyError`.
186
186
187
-
Here's the code with`MyError`and other custom error classes, simplified:
187
+
Voici le code avec`MyError`et d'autres classes d'erreur personnalisées, simplifié:
188
188
189
189
```js run
190
190
classMyErrorextendsError {
@@ -209,19 +209,19 @@ class PropertyRequiredError extends ValidationError {
Now custom errors are much shorter, especially `ValidationError`, as we got rid of the `"this.name = ..."`line in the constructor.
212
+
Maintenant, les erreurs personnalisées sont beaucoup plus courtes, en particulier `ValidationError`, car nous nous sommes débarrassés de la ligne `"this.name = ..."`dans le constructeur.
213
213
214
-
## Wrapping exceptions
214
+
## Le wrapping des exceptions
215
215
216
-
The purpose of the function`readUser`in the code above is "to read the user data". There may occur different kinds of errors in the process. Right now we have `SyntaxError`and`ValidationError`, but in the future `readUser`function may grow and probably generate other kinds of errors.
216
+
Le but de la fonction`readUser`dans le code ci-dessus est "de lire les données de l'utilisateur". Il peut y avoir différents types d’erreurs dans le processus. À l'heure actuelle, nous avons `SyntaxError`et`ValidationError`, mais à l'avenir, la fonction `readUser`pourrait croître et générer probablement d'autres types d'erreurs.
217
217
218
-
The code which calls`readUser`should handle these errors. Right now it uses multiple `if`in the `catch` block, that check the class and handle known errors and rethrow the unknown ones. But if `readUser`function generates several kinds of errors -- then we should ask ourselves: do we really want to check for all error types one-by-one in every code that calls`readUser`?
218
+
Le code qui appelle`readUser`devrait gérer ces erreurs. Actuellement, il utilise plusieurs `if`dans le bloc `catch`, qui vérifient la classe, gèrent les erreurs connues et réexaminent les inconnues. Mais si la fonction `readUser`génère plusieurs types d’erreurs - nous devrions nous demander: voulons-nous vraiment vérifier tous les types d’erreur un par un dans chaque code qui appelle`readUser`?
219
219
220
-
Often the answer is "No": the outer code wants to be "one level above all that". It wants to have some kind of "data reading error". Why exactly it happened -- is often irrelevant (the error message describes it). Or, even better if there is a way to get error details, but only if we need to.
220
+
Souvent, la réponse est "Non": le code externe veut être "au-dessus de tout cela". Il veut avoir une sorte "d'erreur de lecture de données". Pourquoi exactement cela est arrivé est souvent sans importance (le message d'erreur le décrit). Ou encore mieux s'il existe un moyen d'obtenir des détails d'erreur, mais uniquement si nous en avons le besoin.
221
221
222
-
So let's make a new class `ReadError`to represent such errors. If an error occurs inside `readUser`, we'll catch it there and generate `ReadError`. We'll also keep the reference to the original error in its`cause` property. Then the outer code will only have to check for`ReadError`.
222
+
Faisons donc une nouvelle classe `ReadError`pour représenter de telles erreurs. Si une erreur se produit dans `readUser`, nous la détectons et générons `ReadError`. Nous conserverons également la référence à l'erreur d'origine dans sa propriété`cause`. Ensuite, le code externe devra seulement vérifier`ReadError`.
223
223
224
-
Here's the code that defines`ReadError`and demonstrates its use in`readUser`and`try..catch`:
224
+
Voici le code qui définit`ReadError`et illustre son utilisation dans`readUser`et`try..catch`:
225
225
226
226
```js run
227
227
classReadErrorextendsError {
@@ -289,14 +289,14 @@ try {
289
289
}
290
290
```
291
291
292
-
In the code above, `readUser`works exactly as described -- catches syntax and validation errors and throws `ReadError`errors instead (unknown errors are rethrown as usual).
292
+
Dans le code ci-dessus, `readUser`fonctionne exactement comme décrit ci-dessus - corrige les erreurs de syntaxe et de validation et "throw" les erreurs `ReadError`(les erreurs inconnues sont propagées comme d'habitude).
293
293
294
-
So the outer code checks `instanceof ReadError`and that's it. No need to list possible all error types.
294
+
Donc, le code externe vérifie `instanceof ReadError`et c'est tout. Pas besoin de lister tous les types d'erreur possibles.
295
295
296
-
The approach is called "wrapping exceptions", because we take "low level exceptions" and "wrap" them into `ReadError` that is more abstract and more convenient to use for the calling code. It is widely used in object-oriented programming.
296
+
Cette approche, "wrapping exceptions" en anglais, nous permet de prendre les "exceptions de bas niveau" et les "wrapper" dans `ReadError`, qui est plus abstrait et plus pratique à utiliser pour le code appelant. Cette approche est largement utilisée dans la programmation orientée objet.
297
297
298
-
## Summary
298
+
## Résumé
299
299
300
-
- We can inherit from`Error`and other built-in error classes normally, just need to take care of `name`property and don't forget to call`super`.
301
-
- We can use`instanceof`to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from the 3rd-party library and there's no easy way to get the class. Then `name`property can be used for such checks.
302
-
- Wrapping exceptions is a widespread technique: a function handles low-level exceptions and creates higher-level errors instead of various low-level ones. Low-level exceptions sometimes become properties of that object like `err.cause`in the examples above, but that's not strictly required.
300
+
- Nous pouvons hériter de`Error`et d'autres classes d'erreurs intégrées normalement, nous devons juste nous occuper de la propriété `name`et ne pas oublier d'appeler`super`.
301
+
- Nous pouvons utiliser`instanceof`pour vérifier des erreurs particulières. Cela fonctionne aussi avec l'héritage. Mais parfois, nous avons un objet d'erreur provenant d'une bibliothèque tierce et il n'y a pas de moyen facile d'obtenir la classe. Dans ce cas, la propriété `name`peut être utilisée pour de telles vérifications.
302
+
- Le wrapping des exceptions est une technique répandue: une fonction gère les exceptions de bas niveau et crée des erreurs de niveau supérieur au lieu de diverses erreurs de bas niveau. Les exceptions de bas niveau deviennent parfois des propriétés de cet objet comme `err.cause`dans les exemples ci-dessus, mais ce n'est pas strictement requis.
0 commit comments