Lua - Gestione degli errori

Necessità di gestione degli errori

La gestione degli errori è piuttosto critica poiché le operazioni del mondo reale spesso richiedono l'uso di operazioni complesse, che includono operazioni sui file, transazioni di database e chiamate ai servizi web.

In qualsiasi programmazione è sempre richiesta la gestione degli errori. Gli errori possono essere di due tipi che includono,

  • Errori di sintassi
  • Errori di tempo di esecuzione

Errori di sintassi

Gli errori di sintassi si verificano a causa di un uso improprio di vari componenti del programma come operatori ed espressioni. Di seguito è riportato un semplice esempio di errore di sintassi.

a == 2

Come sapete, c'è una differenza tra l'uso di un singolo "uguale a" e del doppio "uguale a". L'utilizzo dell'uno al posto dell'altro può causare un errore. Un "uguale a" si riferisce all'assegnazione mentre un doppio "uguale a" si riferisce al confronto. Allo stesso modo, abbiamo espressioni e funzioni con modalità di implementazione predefinite.

Un altro esempio di errore di sintassi è mostrato di seguito:

for a= 1,10
   print(a)
end

Quando eseguiamo il programma sopra, otterremo il seguente output:

lua: test2.lua:2: 'do' expected near 'print'

Gli errori di sintassi sono molto più facili da gestire rispetto agli errori di runtime poiché l'interprete Lua individua l'errore in modo più chiaro rispetto al caso di errore di runtime. Dall'errore precedente, possiamo sapere facilmente che l'aggiunta di un'istruzione do prima dell'istruzione print è richiesta secondo la struttura Lua.

Errori in fase di esecuzione

In caso di errori di runtime, il programma viene eseguito correttamente, ma può causare errori di runtime dovuti a errori di input o funzioni mal gestite. Di seguito è mostrato un semplice esempio per mostrare l'errore in fase di esecuzione.

function add(a,b)
   return a+b
end

add(10)

Quando creiamo il programma, verrà creato correttamente e verrà eseguito. Una volta eseguito, mostra un errore di runtime.

lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
	test2.lua:2: in function 'add'
	test2.lua:5: in main chunk
	[C]: ?

Si tratta di un errore di runtime, che si era verificato a causa del mancato passaggio di due variabili. Ilb parametro è previsto e qui è nullo e produce un errore.

Funzioni di asserzione ed errore

Per gestire gli errori, utilizziamo spesso due funzioni: assert e error. Di seguito viene mostrato un semplice esempio.

local function add(a,b)
   assert(type(a) == "number", "a is not a number")
   assert(type(b) == "number", "b is not a number")
   return a+b
end

add(10)

Quando eseguiamo il programma sopra, otterremo il seguente output di errore.

lua: test2.lua:3: b is not a number
stack traceback:
	[C]: in function 'assert'
	test2.lua:3: in function 'add'
	test2.lua:6: in main chunk
	[C]: ?

Il error (message [, level])termina l'ultima funzione protetta chiamata e restituisce il messaggio come messaggio di errore. Questo errore di funzione non ritorna mai. Di solito, l'errore aggiunge alcune informazioni sulla posizione dell'errore all'inizio del messaggio. L'argomento level specifica come ottenere la posizione dell'errore. Con il livello 1 (predefinito), la posizione dell'errore è quella in cui è stata chiamata la funzione di errore. Il livello 2 indica l'errore nel punto in cui è stata chiamata la funzione che ha chiamato l'errore; e così via. Il passaggio di un livello 0 evita l'aggiunta di informazioni sulla posizione di errore al messaggio.

pcall e xpcall

Nella programmazione Lua, per evitare di lanciare questi errori e di gestire errori, è necessario utilizzare le funzioni pcall o xpcall.

Il pcall (f, arg1, ...)funzione chiama la funzione richiesta in modalità protetta. Se si verifica un errore nella funzione f, non viene generato un errore. Restituisce solo lo stato di errore. Di seguito è mostrato un semplice esempio di utilizzo di pcall.

function myfunction ()
   n = n/nil
end

if pcall(myfunction) then
   print("Success")
else
	print("Failure")
end

Quando eseguiamo il programma precedente, otterremo il seguente output.

Failure

Il xpcall (f, err)funzione chiama la funzione richiesta e imposta anche il gestore degli errori. Qualsiasi errore all'interno di f non viene propagato; invece, xpcall rileva l'errore, chiama la funzione err con l'oggetto errore originale e restituisce un codice di stato.

Di seguito è mostrato un semplice esempio per xpcall.

function myfunction ()
   n = n/nil
end

function myerrorhandler( err )
   print( "ERROR:", err )
end

status = xpcall( myfunction, myerrorhandler )
print( status)

Quando eseguiamo il programma precedente, otterremo il seguente output.

ERROR:	test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false

Come programmatore, è molto importante assicurarsi di occuparsi della corretta gestione degli errori nei programmi che scrivi. L'utilizzo della gestione degli errori può garantire che le condizioni impreviste oltre le condizioni limite vengano gestite senza disturbare l'utente del programma.