Lua - Manejo de errores

Necesidad de manejo de errores

El manejo de errores es bastante crítico ya que las operaciones del mundo real a menudo requieren el uso de operaciones complejas, que incluyen operaciones de archivos, transacciones de bases de datos y llamadas a servicios web.

En cualquier programación, siempre existe un requisito para el manejo de errores. Los errores pueden ser de dos tipos que incluyen,

  • Errores de sintaxis
  • Errores de tiempo de ejecución

Errores de sintaxis

Los errores de sintaxis ocurren debido al uso inadecuado de varios componentes del programa, como operadores y expresiones. A continuación, se muestra un ejemplo sencillo de error de sintaxis.

a == 2

Como saben, existe una diferencia entre el uso de un solo "igual a" y doble "igual a". Usar uno en lugar del otro puede provocar un error. Un "igual a" se refiere a la asignación, mientras que un doble "igual a" se refiere a la comparación. De manera similar, tenemos expresiones y funciones que tienen sus formas predefinidas de implementación.

Otro ejemplo de error de sintaxis se muestra a continuación:

for a= 1,10
   print(a)
end

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

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

Los errores de sintaxis son mucho más fáciles de manejar que los errores en tiempo de ejecución, ya que el intérprete de Lua localiza el error con mayor claridad que en caso de error en tiempo de ejecución. A partir del error anterior, podemos saber fácilmente que se requiere agregar una instrucción do antes de la instrucción de impresión según la estructura de Lua.

Errores de tiempo de ejecución

En caso de errores de tiempo de ejecución, el programa se ejecuta correctamente, pero puede provocar errores de tiempo de ejecución debido a errores en la entrada o funciones mal manejadas. A continuación se muestra un ejemplo sencillo para mostrar el error de tiempo de ejecución.

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

add(10)

Cuando creamos el programa, se compilará y se ejecutará correctamente. Una vez que se ejecuta, muestra un error de tiempo de ejecución.

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]: ?

Este es un error de tiempo de ejecución, que se produjo debido a que no se pasaron dos variables. losb Se espera el parámetro y aquí es nulo y produce un error.

Funciones de afirmación y error

Para manejar errores, a menudo usamos dos funciones: assert y error. A continuación se muestra un ejemplo sencillo.

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)

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado de error.

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]: ?

los error (message [, level])termina la última función protegida llamada y devuelve un mensaje como mensaje de error. Este error de función nunca vuelve. Por lo general, error agrega información sobre la posición del error al principio del mensaje. El argumento de nivel especifica cómo obtener la posición del error. Con el nivel 1 (el predeterminado), la posición de error es donde se llamó a la función de error. El nivel 2 señala el error al lugar donde se llamó a la función que llamó al error; y así. Pasar un nivel 0 evita la adición de información de posición de error al mensaje.

pcall y xpcall

En la programación de Lua, para evitar lanzar estos errores y manejarlos, necesitamos usar las funciones pcall o xpcall.

los pcall (f, arg1, ...)función llama a la función solicitada en modo protegido. Si ocurre algún error en la función f, no arroja un error. Simplemente devuelve el estado de error. A continuación se muestra un ejemplo sencillo con pcall.

function myfunction ()
   n = n/nil
end

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

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado.

Failure

los xpcall (f, err)function llama a la función solicitada y también establece el controlador de errores. Ningún error dentro de f no se propaga; en su lugar, xpcall detecta el error, llama a la función err con el objeto de error original y devuelve un código de estado.

A continuación se muestra un ejemplo sencillo de xpcall.

function myfunction ()
   n = n/nil
end

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

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

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado.

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

Como programador, es muy importante asegurarse de que se ocupa del manejo adecuado de los errores en los programas que escribe. El uso de la gestión de errores puede garantizar que las condiciones inesperadas más allá de las condiciones límite se manejen sin molestar al usuario del programa.