Lua
Manejo de errores
Buscar..
Usando pcall
pcall
significa "llamada protegida". Se utiliza para agregar el manejo de errores a las funciones. pcall
funciona de forma similar a try-catch
en otros idiomas. La ventaja de pcall
es que la ejecución completa de la secuencia de comandos no se interrumpe si se producen errores en las funciones llamadas con pcall
. Si se produce un error dentro de una función llamada con pcall
produce un error y el resto del código continúa su ejecución.
Sintaxis:
pcall( f , arg1,···)
Valores de retorno:
Devuelve dos valores
- estado (booleano)
- Devuelve true si la función se ejecutó sin errores.
- Devuelve falso si ocurrió un error dentro de la función.
- devuelva el valor de la función o el mensaje de error si se produjo un error dentro del bloque de funciones.
pcall se puede usar para varios casos, sin embargo, uno común es detectar errores de la función que se le ha asignado. Por ejemplo, digamos que tenemos esta función:
local function executeFunction(funcArg, times) then
for i = 1, times do
local ran, errorMsg = pcall( funcArg )
if not ran then
error("Function errored on run " .. tostring(i) .. "\n" .. errorMsg)
end
end
end
Cuando la función dada produce un error en la ejecución 3, el mensaje de error será claro para el usuario de que no proviene de su función, sino de la función que fue asignada a nuestra función. Además, con esto en mente, se puede hacer un BSoD de lujo notificando al usuario. Sin embargo, eso depende de la aplicación que implemente esta función, ya que lo más probable es que una API no lo haga.
Ejemplo A - Ejecución sin pcall
function square(a)
return a * "a" --This will stop the execution of the code and throws an error, because of the attempt to perform arithmetic on a string value
end
square(10);
print ("Hello World") -- This is not being executed because the script was interrupted due to the error
Ejemplo B - Ejecución con pcall
function square(a)
return a * "a"
end
local status, retval = pcall(square,10);
print ("Status: ", status) -- will print "false" because an error was thrown.
print ("Return Value: ", retval) -- will print "input:2: attempt to perform arithmetic on a string value"
print ("Hello World") -- Prints "Hello World"
Ejemplo - Ejecución de código impecable.
function square(a)
return a * a
end
local status, retval = pcall(square,10);
print ("Status: ", status) -- will print "true" because no errors were thrown
print ("Return Value: ", retval) -- will print "100"
print ("Hello World") -- Prints "Hello World"
Manejo de errores en lua.
Suponiendo que tenemos la siguiente función:
function foo(tab)
return tab.a
end -- Script execution errors out w/ a stacktrace when tab is not a table
Vamos a mejorarlo un poco
function foo(tab)
if type(tab) ~= "table" then
error("Argument 1 is not a table!", 2)
end
return tab.a
end -- This gives us more information, but script will still error out
Si no queremos que una función bloquee un programa, incluso en caso de error, en lua es estándar hacer lo siguiente:
function foo(tab)
if type(tab) ~= "table" then return nil, "Argument 1 is not a table!" end
return tab.a
end -- This never crashes the program, but simply returns nil and an error message
Ahora tenemos una función que se comporta así, podemos hacer cosas como esta:
if foo(20) then print(foo(20)) end -- prints nothing
result, error = foo(20)
if result then print(result) else log(error) end
Y si queremos que el programa se bloquee si algo sale mal, todavía podemos hacer esto:
result, error = foo(20)
if not result then error(error) end
Afortunadamente, ni siquiera tenemos que escribir todo eso cada vez; lua tiene una función que hace exactamente esto
result = assert(foo(20))