Bienvenidos sean a este post, hoy continuaremos con los errores y si bien se puede usar cualquier valor como un mensaje de error pero usualmente los mensajes de error son cadenas que describen que fue mal, por eso cuando ocurre un error interno (como intentar indexar un valor que no sea de una tabla) Lua genera el mensaje de error, o de lo contrario el mensaje de error el valor pasado a la funcion error, cuando el mensaje es una cadena Lua intenta agregar alguna informacion sobre la ubicacion donde ocurrio el error:

Anuncios
tinchicus@dbn001dsk:~/lenguaje/lua$ lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> estado, err = pcall(function() a = "a" + 1 end)
> print(err)
stdin:1: attempt to perform arithmetic on a string value
>
> estado, err = pcall(function() error("Mi error") end)
> print(err)
stdin:1: Mi error
>

En este caso podemos ver el error estandar y uno creado por nosotros, la informacion de ubicacion da el nombre del archivo, stdin en el ejemplo, ademas el numero de linea donde ocurrio el error y para este caso es la linea 1, luego tendran la descripcion del error. La funcion error tiene un segundo parametro adicional el cual da el nivel donde deberia reportarse el error, tambien se puede usar el segundo parametro para culpar alguien por el error 😉, tomemos el siguiente ejemplo:

function foo(cdn)
	if type(cdn) ~= "string" then
		error("Se esperaba una cadena")
	end
	... instrucciones ...
end

Veamos la funcion anterior, en este caso lo primero que chequeara si se ejecuto de manera correcta, es decir que el argumento recibido sea de tipo string, vamos a suponer que la funcion es llamada con el siguiente argumento:

foo({x+1})
Anuncios

En este caso Lua apuntara a quien causa el error, la funcion foo, pero no a quien es el verdadero culpable que es el llamador, para corregir este problema se le informa a la funcion error que el error que estas reportando ocurre en el nivel 2 en la jerarquia de llamadas (nivel 1 es la funcion propia), la sintaxis es asi:

function foo(cdn)
	if type(cdn) ~= "string" then
		error("Se esperaba una cadena",2)
	end
	... instrucciones ...
end

Habitualmente cuando un error ocurre queremos mas informacion para la depuracion que solamente la ubicacion donde ocurrio el error, al menos necesitamos un traceback (rastro) mostrando la pila (stack) completa de las llamadas que derivan en el error, cuando pcall devuelve el mensaje de error este destruye parte de la pila (la parte que vino de ahi al punto donde esta el error), como consecuencia si queremos un rastro debemos construirlo antes de lo que regresa la funcion pcall, para hacer esto Lua provee la funcion xpcall.

Esta funcion ademas de poder ser llamada recibe un segundo argumento que es una funcion manejadora de error, y en caso de un error Lua llama a este manejador de error antes que se desarrolle la pila y asi poder usar la libreria de depuracion para conseguir cualquier informacion extra que se necesite sobre el error, dos manejadores de errores comunes son: debug.debug la cual te da un prompt de Lua para poder inspeccionar por ti mismo que estaba sucediendo cuando el error ocurrio y debug.traceback para construir un mensaje de error extendido con un rastro (traceback), este ultimo es la funcion utilizada por el interprete para construir sus mensajes de error, pero tambien nos permite llamarlo en cualquier momento para conseguir un rastro de la ejecucion actual:

print(debug.traceback)
Anuncios

En resumen, hoy hemos visto como manejar mensajes de error, que es un rastro (traceback), con cuales funciones puede manejarse, algunos casos donde los pusimos en practica, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00