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/1-try-catch/article.md
+39-29Lines changed: 39 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,11 +4,11 @@ Non importa quanto siamo bravi a programmare, a volte i nostri scripts contengon
4
4
5
5
Di solito, uno script "muore" (si ferma immediatamente) al verificarsi di un errore, stampandolo in console.
6
6
7
-
Ma esiste il construtto`try..catch` che permette di "catturare" gli errori e, anzichè farlo morire, ci permette di fare qualcosa di più ragionevole.
7
+
Ma esiste il costrutto`try..catch` che permette di "catturare" gli errori e, anziché farlo morire, ci permette di fare qualcosa di più ragionevole.
8
8
9
9
## La sintassi "try..catch"
10
10
11
-
Il construtto`try..catch` è composto da due blocchi principali: `try` e `catch`:
11
+
Il costrutto`try..catch` è composto da due blocchi principali: `try` e `catch`:
12
12
13
13
```js
14
14
try {
@@ -25,12 +25,12 @@ try {
25
25
Funziona in questo modo:
26
26
27
27
1. Per prima cosa, il codice all'interno del blocco `try {...}` viene eseguito.
28
-
2. Se non si verifica alcun errore, allora `catch(err)` viene ignorato: viene eseguito tutto il codice alll'interno del `try` e viene saltato quello all'interno del `catch`.
28
+
2. Se non si verifica alcun errore, allora `catch(err)` viene ignorato: viene eseguito tutto il codice all'interno del `try` e viene saltato quello all'interno del `catch`.
29
29
3. Se si verifica un errore, allora l'esecuzione del resto del codice all'interno del `try` viene interrotta, e si passa all'esecuzione del codice all'interno di `catch(err)`. La variabile `err` (può essere usato ogni nome) contiene un oggetto di tipo Error (Error Object) con i dettagli riguardo a cosa sia successo.
30
30
31
31

32
32
33
-
Quindi, un errore all'interno del blocco `try {…}` non ci ucciderà lo script: avremo la possibilità di gestirlo all'interno del blocco `catch`.
33
+
Quindi, un errore all'interno del blocco `try {…}` non ucciderà lo script: avremo la possibilità di gestirlo all'interno del blocco `catch`.
34
34
35
35
Vediamo degli esempi.
36
36
@@ -85,7 +85,7 @@ try {
85
85
}
86
86
```
87
87
88
-
Il motore di JavaScript dapprima legge il codice, dopodichè lo esegue. Gli errori che si presentano durante la fase di lettura vengono definiti "parse-time" e sono non recuperabili (unrecoverable) (dal codice stesso). Questo perchè il motore non riese a interpretare il codice.
88
+
Il motore di JavaScript dapprima legge il codice, dopodiché lo esegue. Gli errori che si presentano durante la fase di lettura vengono definiti "parse-time" e sono non recuperabili (unrecoverable) (dal codice stesso). Questo perché il motore non riesce a interpretare il codice.
89
89
90
90
Quindi, `try..catch` può solo gestire gli errori presenti in un codice comunque valido. Tali errori vengono chiamati "errori di runtime" (runtime errors) o, a volte, "eccezioni" (exceptions).
91
91
````
@@ -104,7 +104,7 @@ try {
104
104
}
105
105
```
106
106
107
-
Questo accade perchè il codice all'interno della funzione sarà eseguito successivamente, quando il motore già interpretato il construtto`try..catch`.
107
+
Questo accade perché il codice all'interno della funzione sarà eseguito successivamente, quando il motore avrà già interpretato il costrutto`try..catch`.
108
108
109
109
Per intercettare un'eccezione all'interno di una funzione schedulata, `try..catch` dev'essere all'interno di tale funzione
110
110
```js run
@@ -138,7 +138,7 @@ Per tutti gli errori standard, incorporati, l'oggetto errore ha due proprietà p
138
138
`message`
139
139
: Il messaggio testuale con i dettagli dell'errore.
140
140
141
-
Esistono altre proprietà non standard disponibili in diverse condizioni. Uno di quelli più largamente utilizzati e supportati è:
141
+
Esistono altre proprietà non standard disponibili in diverse condizioni. Una di quelle più largamente utilizzate e supportate è:
142
142
143
143
`stack`
144
144
: Lo stack alla chiamata corrente: una stringa con le informazioni inerenti la sequenza delle chiamate effettuate che hanno portato all'errore. Utile a scopo di debugging.
@@ -155,7 +155,7 @@ try {
155
155
alert(err.message); // lalala non è definito
156
156
alert(err.stack); // ReferenceError: lalala non è definito a (...call stack)
157
157
158
-
// Può essere anche visualizzato nel suo compleso
158
+
// Può essere anche visualizzato nel suo complesso
159
159
// L'errore è convertito in una stringa del tipo "name: message"
160
160
alert(err); // ReferenceError: lalala non è definito
161
161
}
@@ -181,7 +181,7 @@ Esploriamo quindi l'uso di `try..catch` nella vita reale.
181
181
182
182
Come già sappiamo, JavaScript supporta il metodo [JSON.parse(str)](mdn:js/JSON/parse) per leggere le variabili codificate in JSON.
183
183
184
-
Generalmente è usato per decodificare i dati ricevuti attranerso la rete, dal server o da altri sorgenti.
184
+
Generalmente è usato per decodificare i dati ricevuti attraverso la rete, dal server o da altri sorgenti.
185
185
186
186
Riceviamo essi e chiamiamo `JSON.parse` così:
187
187
@@ -203,7 +203,7 @@ Puoi trovare maggiori informazioni riguardo il JSON nel capitolo <info:json>.
203
203
204
204
Dovremmo essere soddisfatti di questo? Ovviamente, no!
205
205
206
-
In questo modo, se qualcosa va storto, il visitatore non saprà mai perchè (a meno che non apra la console per sviluppatori). E in genere gli utenti non gradiscono affatto che qualche cosa sia andata storta senza avere alcun messaggio di errore.
206
+
In questo modo, se qualcosa va storto, il visitatore non saprà mai perché (a meno che non apra la console per sviluppatori). E in genere gli utenti non gradiscono affatto che qualche cosa sia andata storta senza avere alcun messaggio di errore.
207
207
208
208
Quindi usiamo `try..catch` per gestire l'errore:
209
209
@@ -220,7 +220,7 @@ try {
220
220
} catch (e) {
221
221
*!*
222
222
// ...l'esecuzione prosegue qui
223
-
alert( "Ci scusiamo, ma i dati contengono errori, proveromo a chiederli nuovamente." );
223
+
alert( "Ci scusiamo, ma i dati contengono errori, proveremo a chiederli nuovamente." );
224
224
alert( e.name );
225
225
alert( e.message );
226
226
*/!*
@@ -266,7 +266,7 @@ throw <error object>
266
266
267
267
Tecnicamente, possiamo usare qualsiasi cosa come oggetto errore (error object). Potrebbe essere una qualunque primitiva, come un numero (number) o una stringa (string), ma è meglio utilizzare un oggetto (object), preferibilmente con le proprietà `name` e `message` (per mantenere la compatibilità con gli errori già inclusi).
268
268
269
-
JavaScript ha già molti construttori integrati per errori generici: `Error`, `SyntaxError`, `ReferenceError`, `TypeError` e altri. Possiamo usarli per creare un oggetto errore.
269
+
JavaScript ha già molti costruttori integrati per errori generici: `Error`, `SyntaxError`, `ReferenceError`, `TypeError` e altri. Possiamo usarli per creare un oggetto errore.
270
270
271
271
La sintassi è:
272
272
@@ -278,7 +278,7 @@ let error = new ReferenceError(message);
278
278
// ...
279
279
```
280
280
281
-
Per gli errori integrati (non per qualunque oggetto, solo per gli errori), la proprietà `name` è esattamente il nome del construttore. E `message` è preso dall'argomento.
281
+
Per gli errori integrati (non per qualunque oggetto, solo per gli errori), la proprietà `name` è esattamente il nome del costruttore. E `message` è preso dall'argomento.
282
282
283
283
Ad esempio:
284
284
@@ -304,7 +304,7 @@ try {
304
304
305
305
Come possiamo vedere, è un `Errore di Sintassi` (SyntaxError).
306
306
307
-
Vediamo l'altro caso, in cui l'assenza di `name` è un errore, poichè gli utenti devono avere la proprietà `name`.
307
+
Vediamo l'altro caso, in cui l'assenza di `name` è un errore, poiché gli utenti devono avere la proprietà `name`.
308
308
309
309
Quindi eseguiamo:
310
310
@@ -334,7 +334,7 @@ Quindi `catch` diventa un singolo posto per la gestione di tutti gli errori: sia
334
334
335
335
## Rethrowing
336
336
337
-
Nel precedente esempio abbiamo usato `try..catch` per gestire i dati non corretti. Ma è possible che *un altro errore inaspettato* si verifichi all'interno del blocco `try {...}`? Come un errore di programmazione (variabile non definita) o qualcos'altro, non solo qualcosa come i "dati non corretti".
337
+
Nel precedente esempio abbiamo usato `try..catch` per gestire i dati non corretti. Ma è possibile che *un altro errore inaspettato* si verifichi all'interno del blocco `try {...}`? Come un errore di programmazione (variabile non definita) o qualcos'altro, non solo qualcosa come i "dati non corretti".
338
338
339
339
Come questo:
340
340
@@ -381,6 +381,16 @@ try {
381
381
382
382
Possiamo ottenere il nome della classe di errore dalla proprietà `err.name`. Tutti gli errori nativi la possiedono. Un'altra opzione può esser quella di leggere `err.constructor.name`.
383
383
384
+
La regola è semplice:
385
+
386
+
**Catch dovrebbe processore solamente gli errori che riconosce e "rilanciare" (rethrow) tutti gli altri.**
387
+
388
+
La tecnica "rethrowing" può essere spiegata più in dettaglio come:
2. Se non sappiamo come gestirlo, allora ne usciremo con `throw err`.
393
+
384
394
Nel codice seguente, useremo rethrowing in modo che `catch` gestisca solamente un `SyntaxError`:
385
395
386
396
```js run
@@ -412,7 +422,7 @@ try {
412
422
}
413
423
```
414
424
415
-
Genereremo un errore nel blocco `catch` alla linea `(*)` "uscendo" dal `try..catch` e potermo catturare nuovamente quest'errore con un construtto`try..catch` più esterno (se esiste), altrimenti lo script morirà.
425
+
Genereremo un errore nel blocco `catch` alla linea `(*)` "uscendo" dal `try..catch` e potremo catturare nuovamente quest'errore con un costrutto`try..catch` più esterno (se esiste), altrimenti lo script morirà.
416
426
417
427
Quindi, attualmente il blocco `catch` gestisce solamente gli errori che conosce e per cui è stato istruito e "ignora" tutti gli altri.
418
428
@@ -452,11 +462,11 @@ In questo caso `readData` sa solamente come gestire un `SyntaxError`, mentre il
452
462
453
463
Aspetta, non è tutto.
454
464
455
-
Il construtto`try..catch` può avere una o più clausole: `finally`.
465
+
Il costrutto`try..catch` può avere una o più clausole: `finally`.
456
466
457
467
Se esiste, il codice all'interno delle clausole verrà eseguito in ogni caso:
458
468
459
-
- dopo `try`, se non si sono veriticati errori,
469
+
- dopo `try`, se non si sono verificati errori,
460
470
- dopo `catch`, se si sono verificati errori.
461
471
462
472
La sintassi estesa sarà più o meno così:
@@ -493,7 +503,7 @@ La clausola `finally` è spesso utilizzata quando iniziamo a fare qualcosa e vog
493
503
494
504
Per esempio, vogliamo misurare il tempo che impiega una funzione di Fibonacci `fib(n)`. Naturalmente, dobbiamo iniziare la misurazione prima che essa venga eseguita e terminarla subito dopo. Ma cosa accade se si verifica un errore durante il richiamo della funzione? In particolare, l'implementazione di `fib(n)` nel codice che segue ritorna un errore in caso di numeri negativi o non interi.
495
505
496
-
La clausola `finally` è il posto migliore dove termicare la misurazione senza dover tener conto di cosa sia successo.
506
+
La clausola `finally` è il posto migliore dove terminare la misurazione senza dover tener conto di cosa sia successo.
497
507
498
508
In questo caso `finally` garantisce la misurazione del tempo impiegato correttamente in entrambe le situazioni -- sia nel caso di un'esecuzione corretta di `fib` che nel caso si verifichi un errore in essa:
499
509
@@ -526,15 +536,15 @@ alert(result || "si è verificato un errore");
526
536
alert( `l'esecuzione è durata ${diff}ms` );
527
537
```
528
538
529
-
Possiamo verificare il codice eseguendelo e inserendo `35` al `prompt` -- verrà eseguito normalmente, `finally` dopo `try`. E se inseriamo `-1` -- ci sarà un errore immediato, e l'esecuzione durerà `0ms`. Entrambe le misurazioni saranno corrette.
539
+
Possiamo verificare il codice eseguendolo e inserendo `35` al `prompt` -- verrà eseguito normalmente, `finally` dopo `try`. E se inseriamo `-1` -- ci sarà un errore immediato, e l'esecuzione durerà `0ms`. Entrambe le misurazioni saranno corrette.
530
540
531
541
In altre parola, la funzione potrà terminare con `return` o `throw`, non avrà alcuna importanza. La clausola `finally` verrà eseguita in ogni caso.
532
542
533
543
534
544
```smart header="Le variabili sono locali all'interno di `try..catch..finally`"
535
545
Presta attenzione al fatto che le variabili `result` e `diff` nel codice precedente sono dichiarate prima del `try..catch`.
536
546
537
-
Altrimenti, se dichiariamo `let` all'internod del blocco `try`, risulterà visibile solamente all'interno del blocco stesso.
547
+
Altrimenti, se dichiariamo `let` all'interno del blocco `try`, risulterà visibile solamente all'interno del blocco stesso.
538
548
```
539
549
540
550
````smart header="`finally` e `return`"
@@ -565,7 +575,7 @@ alert( func() ); // prima viene eseguito l'alert del finally, e successivamente
565
575
566
576
````smart header="`try..finally`"
567
577
568
-
Anche il construtto `try..finally`, senza la clausola `catch` può risultare utile. Lo useremo se non vogliamo gestire l'errore in questo momento (ignorandolo), ma vogliamo essere sicuri che il processo che abbiamo avviato sia finalizzato ugualmente.
578
+
Anche il costrutto `try..finally`, senza la clausola `catch` può risultare utile. Lo useremo se non vogliamo gestire l'errore in questo momento (ignorandolo), ma vogliamo essere sicuri che il processo che abbiamo avviato sia finalizzato ugualmente.
569
579
570
580
```js
571
581
function func() {
@@ -577,7 +587,7 @@ function func() {
577
587
}
578
588
}
579
589
```
580
-
Nel codice qui sopra, un errore all'interno di `try` vi farà uscire sempre fuori dal construtto, perchè non c'è `catch`. Ma `finally` verrà eseguito ugualmente prima che il flusso lascierà la funzione.
590
+
Nel codice qui sopra, un errore all'interno di `try` vi farà uscire sempre fuori dal costrutto, perché non c'è `catch`. Ma `finally` verrà eseguito ugualmente prima che il flusso lascerà la funzione.
581
591
````
582
592
583
593
## Catch globale
@@ -590,7 +600,7 @@ Immaginiamo di incorrere in un errore fatale fuori dal `try..catch`, e lo script
590
600
591
601
Esiste un modo per reagire a un situazione simile? Possiamo creare un log dell'errore, mostrare qualcosa all'utente (che normalmente non vede i messaggi di errore), ecc.
592
602
593
-
Non esiste nulla nelle specifiche, ma l'ambuente in genere ci viene incontro, poichè risulta veramente utile. Ad esempio, Node.js ha [`process.on("uncaughtException")`](https://nodejs.org/api/process.html#process_event_uncaughtexception) per questo. E nel browser possiamo assegnare una funzione alla proprietà speciale [window.onerror](mdn:api/GlobalEventHandlers/onerror), che verrà eseguita nel caso di un errore non catturato.
603
+
Non esiste nulla nelle specifiche, ma l'ambiente in genere ci viene incontro, poiché risulta veramente utile. Ad esempio, Node.js ha [`process.on("uncaughtException")`](https://nodejs.org/api/process.html#process_event_uncaughtexception) per questo. E nel browser possiamo assegnare una funzione alla proprietà speciale [window.onerror](mdn:api/GlobalEventHandlers/onerror), che verrà eseguita nel caso di un errore non catturato.
594
604
595
605
La sintassi:
596
606
@@ -630,7 +640,7 @@ Ad esempio:
630
640
</script>
631
641
```
632
642
633
-
Il ruolo del gestore globale `window.onerror` non è quello di risolvere l'esecuzione dello the script -- cosa probabilmente impossibile nel'eventualità di errori di programmazione, ma di inviare messaggi di errore agli sviluppatori.
643
+
Il ruolo del gestore globale `window.onerror` non è quello di risolvere l'esecuzione dello the script -- cosa probabilmente impossibile nel'eventualità di errori di programmazione, ma d'inviare messaggi di errore agli sviluppatori.
634
644
635
645
Esistono anche dei web-services che forniscono servizi di error-logging, come <https://errorception.com> o <http://www.muscula.com>.
636
646
@@ -643,7 +653,7 @@ Funziona all'incirca così:
643
653
644
654
## Riepilogo
645
655
646
-
Il construtto`try..catch` permette la gestione degli errori al momento dell'esecuzione. Letteralente permette di "provare" ("try") il codice e "catturare" ("catch") gli errori che si possono verificare.
656
+
Il costrutto`try..catch` permette la gestione degli errori al momento dell'esecuzione. Letteralmente permette di "provare" ("try") il codice e "catturare" ("catch") gli errori che si possono verificare.
647
657
648
658
La sintassi è:
649
659
@@ -658,18 +668,18 @@ try {
658
668
}
659
669
```
660
670
661
-
Sia la sezione `catch` che `finally` possono essere omesse, quindi i construtti brevi `try..catch` e `try..finally` sono ugualmente validi.
671
+
Sia la sezione `catch` che `finally` possono essere omesse, quindi i costrutti brevi `try..catch` e `try..finally` sono ugualmente validi.
662
672
663
673
L'oggetto errore ha le seguenti proprietà:
664
674
665
675
-`message` -- il messaggio di errore "human-readable".
666
676
-`name` -- la stringa con il nome dell'errore (error constructor name).
667
677
-`stack` (non standard, ma ben supportato) -- lo stack al momento della creazione dell'errore.
668
678
669
-
Se un oggetto errore non è necessario, possiamo ometterlo usando `catch {`anzichè`catch(err) {`.
679
+
Se un oggetto errore non è necessario, possiamo ometterlo usando `catch {`anziché`catch(err) {`.
670
680
671
681
Possiamo anche generare un nostro errore personalizzato usando l'operatore `throw`. Tecnicamente, l'argomento di `throw` può essere qualunque cosa, ma in genere è un oggetto errore (object error) che estende la classe integrata `Error`. Puoi leggerne di più nel prossimo capitolo.
672
682
673
683
*Rethrowing* è un pattern veramente importante per la gestione degli errori: un blocco `catch` in genere si aspetta e gestisce un particolare tipo di errore, quindi dovrebbe "rilanciare" (rethrow) gli errori che non è in grado di gestire.
674
684
675
-
In ogni caso, se non abbiamo `try..catch`, molti ambienti permettono di impostare un gestore "globale" per intercettare gli errori che ci "buttano fuori". All'interno del browser c'è `window.onerror`.
685
+
In ogni caso, se non abbiamo `try..catch`, molti ambienti permettono d'impostare un gestore "globale" per intercettare gli errori che ci "buttano fuori". All'interno del browser c'è `window.onerror`.
0 commit comments