Skip to content

Commit ba80ff2

Browse files
authored
Merge branch 'master' into master
2 parents b769e5c + c6d7983 commit ba80ff2

File tree

1 file changed

+39
-29
lines changed

1 file changed

+39
-29
lines changed

1-js/10-error-handling/1-try-catch/article.md

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ Non importa quanto siamo bravi a programmare, a volte i nostri scripts contengon
44

55
Di solito, uno script "muore" (si ferma immediatamente) al verificarsi di un errore, stampandolo in console.
66

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

99
## La sintassi "try..catch"
1010

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`:
1212

1313
```js
1414
try {
@@ -25,12 +25,12 @@ try {
2525
Funziona in questo modo:
2626

2727
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`.
2929
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.
3030

3131
![](try-catch-flow.svg)
3232

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

3535
Vediamo degli esempi.
3636

@@ -85,7 +85,7 @@ try {
8585
}
8686
```
8787
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.
8989
9090
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).
9191
````
@@ -104,7 +104,7 @@ try {
104104
}
105105
```
106106
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`.
108108

109109
Per intercettare un'eccezione all'interno di una funzione schedulata, `try..catch` dev'essere all'interno di tale funzione
110110
```js run
@@ -138,7 +138,7 @@ Per tutti gli errori standard, incorporati, l'oggetto errore ha due proprietà p
138138
`message`
139139
: Il messaggio testuale con i dettagli dell'errore.
140140

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 è:
142142

143143
`stack`
144144
: 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 {
155155
alert(err.message); // lalala non è definito
156156
alert(err.stack); // ReferenceError: lalala non è definito a (...call stack)
157157

158-
// Può essere anche visualizzato nel suo compleso
158+
// Può essere anche visualizzato nel suo complesso
159159
// L'errore è convertito in una stringa del tipo "name: message"
160160
alert(err); // ReferenceError: lalala non è definito
161161
}
@@ -181,7 +181,7 @@ Esploriamo quindi l'uso di `try..catch` nella vita reale.
181181

182182
Come già sappiamo, JavaScript supporta il metodo [JSON.parse(str)](mdn:js/JSON/parse) per leggere le variabili codificate in JSON.
183183

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

186186
Riceviamo essi e chiamiamo `JSON.parse` così:
187187

@@ -203,7 +203,7 @@ Puoi trovare maggiori informazioni riguardo il JSON nel capitolo <info:json>.
203203

204204
Dovremmo essere soddisfatti di questo? Ovviamente, no!
205205

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

208208
Quindi usiamo `try..catch` per gestire l'errore:
209209

@@ -220,7 +220,7 @@ try {
220220
} catch (e) {
221221
*!*
222222
// ...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." );
224224
alert( e.name );
225225
alert( e.message );
226226
*/!*
@@ -266,7 +266,7 @@ throw <error object>
266266

267267
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).
268268

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

271271
La sintassi è:
272272

@@ -278,7 +278,7 @@ let error = new ReferenceError(message);
278278
// ...
279279
```
280280

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

283283
Ad esempio:
284284

@@ -304,7 +304,7 @@ try {
304304

305305
Come possiamo vedere, è un `Errore di Sintassi` (SyntaxError).
306306

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

309309
Quindi eseguiamo:
310310

@@ -334,7 +334,7 @@ Quindi `catch` diventa un singolo posto per la gestione di tutti gli errori: sia
334334

335335
## Rethrowing
336336

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".
338338

339339
Come questo:
340340

@@ -381,6 +381,16 @@ try {
381381

382382
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`.
383383

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:
389+
390+
1. Catch intercetta tutti gli errori.
391+
2. Nel blocco `catch(err) {...}` analizziamo l'oggetto errore (Object Error) `err`.
392+
2. Se non sappiamo come gestirlo, allora ne usciremo con `throw err`.
393+
384394
Nel codice seguente, useremo rethrowing in modo che `catch` gestisca solamente un `SyntaxError`:
385395

386396
```js run
@@ -412,7 +422,7 @@ try {
412422
}
413423
```
414424

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à.
416426

417427
Quindi, attualmente il blocco `catch` gestisce solamente gli errori che conosce e per cui è stato istruito e "ignora" tutti gli altri.
418428

@@ -452,11 +462,11 @@ In questo caso `readData` sa solamente come gestire un `SyntaxError`, mentre il
452462

453463
Aspetta, non è tutto.
454464

455-
Il construtto `try..catch` può avere una o più clausole: `finally`.
465+
Il costrutto `try..catch` può avere una o più clausole: `finally`.
456466

457467
Se esiste, il codice all'interno delle clausole verrà eseguito in ogni caso:
458468

459-
- dopo `try`, se non si sono veriticati errori,
469+
- dopo `try`, se non si sono verificati errori,
460470
- dopo `catch`, se si sono verificati errori.
461471

462472
La sintassi estesa sarà più o meno così:
@@ -493,7 +503,7 @@ La clausola `finally` è spesso utilizzata quando iniziamo a fare qualcosa e vog
493503

494504
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.
495505

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

498508
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:
499509

@@ -526,15 +536,15 @@ alert(result || "si è verificato un errore");
526536
alert( `l'esecuzione è durata ${diff}ms` );
527537
```
528538

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

531541
In altre parola, la funzione potrà terminare con `return` o `throw`, non avrà alcuna importanza. La clausola `finally` verrà eseguita in ogni caso.
532542

533543

534544
```smart header="Le variabili sono locali all'interno di `try..catch..finally`"
535545
Presta attenzione al fatto che le variabili `result` e `diff` nel codice precedente sono dichiarate prima del `try..catch`.
536546

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.
538548
```
539549
540550
````smart header="`finally` e `return`"
@@ -565,7 +575,7 @@ alert( func() ); // prima viene eseguito l'alert del finally, e successivamente
565575
566576
````smart header="`try..finally`"
567577
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.
569579
570580
```js
571581
function func() {
@@ -577,7 +587,7 @@ function func() {
577587
}
578588
}
579589
```
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.
581591
````
582592

583593
## Catch globale
@@ -590,7 +600,7 @@ Immaginiamo di incorrere in un errore fatale fuori dal `try..catch`, e lo script
590600

591601
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.
592602

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

595605
La sintassi:
596606

@@ -630,7 +640,7 @@ Ad esempio:
630640
</script>
631641
```
632642

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

635645
Esistono anche dei web-services che forniscono servizi di error-logging, come <https://errorception.com> o <http://www.muscula.com>.
636646

@@ -643,7 +653,7 @@ Funziona all'incirca così:
643653

644654
## Riepilogo
645655

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

648658
La sintassi è:
649659

@@ -658,18 +668,18 @@ try {
658668
}
659669
```
660670

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

663673
L'oggetto errore ha le seguenti proprietà:
664674

665675
- `message` -- il messaggio di errore "human-readable".
666676
- `name` -- la stringa con il nome dell'errore (error constructor name).
667677
- `stack` (non standard, ma ben supportato) -- lo stack al momento della creazione dell'errore.
668678

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) {`.
670680

671681
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.
672682

673683
*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.
674684

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

Comments
 (0)