Skip to content

Commit 5af11dc

Browse files
authored
Merge pull request #85 from TevaHenry/Custom-errors
Custom errors, extending Error
2 parents c9fc5c3 + 4f097bf commit 5af11dc

File tree

3 files changed

+56
-56
lines changed

3 files changed

+56
-56
lines changed

1-js/10-error-handling/2-custom-errors/1-format-error/task.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ importance: 5
22

33
---
44

5-
# Inherit from SyntaxError
5+
# Hériter de SyntaxError
66

7-
Create a class `FormatError` that inherits from the built-in `SyntaxError` class.
7+
Créez une classe `FormatError` qui hérite de la classe `SyntaxError` intégrée.
88

9-
It should support `message`, `name` and `stack` properties.
9+
Il devrait supporter les propriétés `message`, `name` et `stack`.
1010

11-
Usage example:
11+
Exemple d'utilisation:
1212

1313
```js
1414
let err = new FormatError("formatting error");
@@ -18,5 +18,5 @@ alert( err.name ); // FormatError
1818
alert( err.stack ); // stack
1919

2020
alert( err instanceof FormatError ); // true
21-
alert( err instanceof SyntaxError ); // true (because inherits from SyntaxError)
21+
alert( err instanceof SyntaxError ); // true (hérite de SyntaxError)
2222
```

1-js/10-error-handling/2-custom-errors/article.md

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
1-
# Custom errors, extending Error
1+
# Les erreurs personnalisées, Étendre Error
22

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.
44

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`.
66

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.
88

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.
1010

11-
## Extending Error
11+
## Étendre Error
1212

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.
1414

15-
Here's an example of how a valid `json` may look:
15+
Voici un exemple de l'apparence d'un `json` valide:
1616
```js
1717
let json = `{ "name": "John", "age": 30 }`;
1818
```
1919

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.
2121

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.
2323

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.
2525

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:
2727

2828
```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
3030
class Error {
3131
constructor(message) {
3232
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>; // non standard, mais la plupart des environnements le supportent
3535
}
3636
}
3737
```
3838

39-
Now let's inherit `ValidationError` from it and try it in action:
39+
Maintenant, héritons de `ValidationError` et mettons-le en action:
4040

4141
```js run untrusted
4242
*!*
@@ -57,15 +57,15 @@ try {
5757
} catch(err) {
5858
alert(err.message); // Whoops!
5959
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
6161
}
6262
```
6363

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`.
6565

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.
6767

68-
Let's try to use it in `readUser(json)`:
68+
Essayons de l'utiliser dans `readUser(json)`:
6969

7070
```js run
7171
class ValidationError extends Error {
@@ -89,7 +89,7 @@ function readUser(json) {
8989
return user;
9090
}
9191

92-
// Working example with try..catch
92+
// un example avec try..catch
9393

9494
try {
9595
let user = readUser('{ "age": 25 }');
@@ -101,31 +101,31 @@ try {
101101
} else if (err instanceof SyntaxError) { // (*)
102102
alert("JSON Syntax Error: " + err.message);
103103
} else {
104-
throw err; // unknown error, rethrow it (**)
104+
throw err; // erreur inconnue, propager le (**)
105105
}
106106
}
107107
```
108108

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`.
110110

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 `(*)`.
112112

113-
We could also look at `err.name`, like this:
113+
Nous pourrions aussi regarder `err.name`, comme ceci:
114114

115115
```js
116116
// ...
117-
// instead of (err instanceof SyntaxError)
117+
// au lieu de (err instanceof SyntaxError)
118118
} else if (err.name == "SyntaxError") { // (*)
119119
// ...
120120
```
121121
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.
123123
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".
125125
126-
## Further inheritance
126+
## Héritage complémentaire
127127
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.
129129
130130
```js run
131131
class ValidationError extends Error {
@@ -159,7 +159,7 @@ function readUser(json) {
159159
return user;
160160
}
161161

162-
// Working example with try..catch
162+
// example avec try..catch
163163

164164
try {
165165
let user = readUser('{ "age": 25 }');
@@ -173,18 +173,18 @@ try {
173173
} else if (err instanceof SyntaxError) {
174174
alert("JSON Syntax Error: " + err.message);
175175
} else {
176-
throw err; // unknown error, rethrow it
176+
throw err; // erreur inconnue, propager le
177177
}
178178
}
179179
```
180180
181-
The new class `PropertyRequiredError` is easy to use: we only need to pass the property name: `new PropertyRequiredError(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é: `new PropertyRequiredError(property)`. Le `message` est généré par le constructeur.
182182
183-
Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = <class name>` 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 = <class name>` 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.
184184
185-
Let's call it `MyError`.
185+
Appelons cela `MyError`.
186186
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é:
188188
189189
```js run
190190
class MyError extends Error {
@@ -209,19 +209,19 @@ class PropertyRequiredError extends ValidationError {
209209
alert( new PropertyRequiredError("field").name ); // PropertyRequiredError
210210
```
211211
212-
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.
213213
214-
## Wrapping exceptions
214+
## Le wrapping des exceptions
215215
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.
217217
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`?
219219
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.
221221
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`.
223223
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`:
225225
226226
```js run
227227
class ReadError extends Error {
@@ -289,14 +289,14 @@ try {
289289
}
290290
```
291291
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).
293293
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.
295295
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.
297297
298-
## Summary
298+
## Résumé
299299
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.

1-js/10-error-handling/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
# Error handling
1+
# La gestion des erreurs

0 commit comments

Comments
 (0)