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

  1. estado (booleano)
  • Devuelve true si la función se ejecutó sin errores.
  • Devuelve falso si ocurrió un error dentro de la función.
  1. 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))


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow