Un nuovo modo di gestire gli errori

Tradotto automaticamente da Deepl

Abbiamo recentemente introdotto un nuovo meccanismo di gestione degli errori, utilizzando il nuovo comando throw().
Questo ha segnato il primo passo verso un nuovo sistema di gestione degli errori, posizionato il più vicino possibile al codice che li genera.
Nella fase successiva, con 4D v20 R4, amplieremo questo approccio per intercettare gli errori durante l’esecuzione delle espressioni.
Entriamo nei dettagli.

try(), una nuova parola chiave utile

Con l’introduzione di 4D v20 R4, gli sviluppatori possono accedere a una nuova e utile parola chiave: Try(Expression). La parola chiave Try() consente agli sviluppatori di eseguire un’espressione racchiusa tra parentesi e di intercettare senza problemi eventuali errori lanciati durante l’esecuzione. Questi errori possono essere gestiti con il comando Last errors subito dopo l’esecuzione dell’espressione. Ciò consente di definire la gestione degli errori il più vicino possibile al codice che li ha generati e di utilizzare eventualmente variabili locali.

Scenari di esempio prima delle spiegazioni dettagliate

Divisione per zero

Consideriamo uno scenario semplice: la divisione per zero. L’esempio seguente mostra un metodo di divisione euclidea che lancia un errore e restituisce arbitrariamente zero se il divisore è zero. Con Try(), gli sviluppatori possono gestire gli errori in modo più elegante:

#DECLARE($dividend: Real; $divisor: Real)->$result: Real
If ($divisor=0)
$result :=0
throw (-12345; "Divisione per zero!")
Else
$result :=($dividend/$divisor)
End if

$result:=Try(division($dividend; $divisor))
If (Last errors#Null)
// Error management
logErrors (Last errors)
End if

ACCESSO A UN DOCUMENTO

La gestione degli errori di accesso a un documento diventa più semplice se il documento non esiste.
Per evitare che venga visualizzata la finestra di dialogo di errore 4D, è necessario installare un gestore di errori e scrivere il codice di gestione degli errori all’interno di questo gestore:

$previousErrorHandler:=Method called on error
ON ERR CALL ("errorOpenDoc")
var $fileHandle : 4D.FileHandle:=File($path).open()
If ($fileHandle#Null)
ON ERR CALL ("errorReadDoc")
$text :=$fileHandle.readText()
If (Last errors#Null)
$text :="Errore nella lettura del file"
End if
End if
ON ERR CALL ($previousErrorHandler)

Con la parola chiave Try(), tutto può essere scritto nella stessa sezione di codice, accedendo alle variabili locali e semplificando la leggibilità:

var $fileHandle : 4D.FileHandle:=Try(File($path).open())
If ($fileHandle#Null)
$text :=Try($fileHandle.readText()) || "Errore nella lettura del file"
End if

Funzione di salvataggio ORDA

Un altro caso d’uso robusto riguarda la funzione ORDA save(), che può generare errori prevedibili e imprevedibili.
Gli errori prevedibili, come il blocco di un’entità, possono essere gestiti direttamente attraverso l’attributo result success. Tuttavia, gli errori imprevedibili, come i duplicati delle chiavi primarie, richiedono un gestore di errori installato con il comando ON ERR CALL altrimenti si visualizzerebbe la finestra di dialogo di errore 4D:

var $customer : cs.CustomerEntity
// Do something with the $customer entity
$previousErrorHandler :=Method called on error
ON ERR CALL ("errorSaveManagement")
$result :=$customer.save()
ON ERR CALL ($previousErrorHandler)
If (Not($result.success))
Case of
: ($result.status=3)
// Locked entity management
: ($result.status=4)
// Other error management
End case
End if

Ma ora la parola chiave Try() diventa un prezioso alleato per gestire errori prevedibili e imprevedibili senza mostrare la finestra di dialogo degli errori 4D:

var $customer : cs.CustomerEntity
// Do something with the $customer entity
$result :=Try($customer.save())
If (Not($result.success))
Case of
: ($result.status=3)
// Locked entity management
: ($result.status=4)
// Other error management
End case
End if

Esecuzione dell’espressione

La parola chiave Try() accetta qualsiasi espressione 4D tra le parentesi, siano esse variabili, assegnazioni, metodi, funzioni o altro. In caso di errore, il flusso di esecuzione si interrompe e ritorna all’ultima parola chiave Try() incontrata (la prima trovata nello stack delle chiamate). Di conseguenza, è sufficiente controllare lo stack degli errori dopo l’esecuzione dell’espressione per sapere se si sono verificati errori.
Si noti che se viene generato un errore utilizzando il comando throw() in modalità differita, il flusso di esecuzione continua fino alla fine dell’esecuzione del metodo/funzione corrente, fornendo un modo semplice per gestire la propagazione degli errori.

Risultati

Se l’esecuzione ha successo, Try() restituisce il risultato dell’espressione.
In caso di errore, restituisce l’ultimo risultato dell’espressione o ‘undefined’ se non disponibile.
Se l’espressione non definisce alcun risultato (ad esempio, un metodo o un comando senza risultato), la parola chiave try restituisce ‘undefined’.

Informazioni sullo stack degli errori

La pila degli errori corrente viene cancellata prima dell’esecuzione dell’espressione, offrendo una tabula rasa per la gestione degli errori nel contesto di Try(). Gli errori riscontrati durante l’esecuzione dell’espressione vengono aggiunti allo stack degli errori, fornendo agli sviluppatori informazioni complete per il debug.

Gestione degli errori

Se non è stato definito alcun gestore di errori utilizzando il comando ON ERR CALL la finestra di dialogo degli errori non interromperà l’esperienza dell’utente con Try().
I gestori di errori globali e locali impostati prima di entrare nel blocco Try() non verranno richiamati, garantendo una separazione netta tra il contesto Try e il resto del codice.
Se l’espressione definisce un gestore di errori globale o locale per il database corrente, questo verrà invocato quando si verifica un errore durante l’esecuzione.

Esplorare nuovi orizzonti nella gestione degli errori

Questa nuova funzione apre un mondo di possibilità per la gestione degli errori. Ma è solo il secondo passo nella nuova era della gestione degli errori 4D, che apre la strada ai blocchi try-catch multilinea!
Condividete i vostri pensieri e le vostre esperienze sul nostro forum e fateci sapere cosa ne pensate di questa nuova funzionalità.

Buona programmazione!

Avatar
- Product Owner -Damien Fuzeau è entrato a far parte del team 4D Product nel febbraio 2019. In qualità di Product Owner, si occupa di scrivere le storie degli utenti e di tradurle in specifiche funzionali. Il suo lavoro consiste anche nell'assicurarsi che le implementazioni delle funzionalità fornite soddisfino le esigenze dei clienti.Damien si è laureato all'Università di Nantes in ingegneria del software. Ha trascorso più di 23 anni nella sua precedente azienda, prima come sviluppatore (scoprendo 4D nel 1997), poi come responsabile dell'ingegneria e architetto software. Questa azienda è un partner OEM di 4D e ha distribuito software aziendali basati su 4D per migliaia di utenti, su centinaia di server. Damien è quindi abituato allo sviluppo e alla distribuzione di 4D in un contesto multilingue.