Manejo de excepciones en Julia

Cualquier condición inesperada que ocurre durante la ejecución normal del programa se denomina Excepción. El manejo de excepciones en Julia es el mecanismo para superar esta situación al trazar una ruta alternativa para continuar con la ejecución normal del programa. Si las excepciones no se controlan, el programa finaliza abruptamente. Las acciones a realizar en caso de ocurrencia de una excepción no son conocidas por el programa. El proceso de evitar que el compilador se bloquee con tales excepciones se denomina Manejo de excepciones.

Manejo de excepciones

Julia permite el manejo de excepciones mediante el uso de un bloque try-catch. El bloque de código que posiblemente puede generar una excepción se coloca en el bloque try y el bloque catch maneja la excepción generada. La excepción se propaga a través de la pila de llamadas hasta que se encuentra un bloque try-catch. Consideremos el siguiente código. Aquí tratamos de encontrar la raíz cuadrada de -1 que arroja «DomainError» y el programa termina. 

Python3

println(sqrt(-1))

Producción:

ERROR: LoadError: DomainError:
sqrt will only return a complex result if called with a complex argument. Try sqrt(complex(x)).
Stacktrace:
 [1] sqrt(::Int64) at ./math.jl:434
while loading /home/cg/root/945981/main.jl, in expression starting on line 1

En ausencia de un bloque try-catch, el programa termina abruptamente. Sin embargo, podemos evitar la finalización del programa manejando la excepción con gracia usando un bloque try-catch. 

Python3

println("Before Exception")
try
    sqrt(-1)
catch
    println("Cannot find the square root of negative numbers")
end
println("After Exception")

Producción:

Before Exception
Cannot find the square root of negative numbers
After Exception

El bloque try-catch también permite almacenar la excepción en una variable. El método de usar el bloque catch para manejar múltiples tipos de excepciones se llama método canónico. El siguiente ejemplo calcula la raíz cuadrada del tercer elemento de x si x es indexable; de ​​lo contrario, asume que x es un número real y devuelve su raíz cuadrada. 

Python3

sqrt_third(x) = try
        println(sqrt(x[3]))
    catch y
        if isa(y, DomainError)
            println(sqrt(complex(x[3], 0)))
        elseif isa(y, BoundsError)
            println(sqrt(x))
        end
    end
 
 
sqrt_third([1 9 16 25])
sqrt_third([1 -4 9 16])
sqrt_third(25)
sqrt_third(-9)

Producción:

4.0
3.0
5.0
ERROR: LoadError: DomainError:
Stacktrace:
 [1] sqrt_third(::Int64) at /home/cg/root/945981/main.jl:7
while loading /home/cg/root/945981/main.jl, in expression starting on line 15

Uso de la cláusula Finalmente

El bloque finalmente se ejecuta independientemente de que ocurra una excepción. El código dentro del bloque finalmente se puede usar para cerrar recursos como archivos abiertos u otros trabajos de limpieza. 

Python3

try
    f = open("file.txt")
catch
    println("No such file exists")
finally
    println("After exception")
end

Producción:

No such file exists
After exception

Lanzar una excepción

La función throw() se puede usar para lanzar excepciones personalizadas. Los siguientes ejemplos muestran un error lanzado desde una función y manejado por el bloque catch. La función error() se usa para producir una ErrorException. 

Python3

function f(x)
    if(x < 5)
        throw(error())
    end
    return sqrt(x)
end
 
try
    println(f(9))
    println(f(1))
catch e
    println("Argument less than 5")
end

Producción:

3.0
Argument less than 5

También se pueden lanzar excepciones desde el bloque catch. El bloque catch puede incluir algún código para manejar la excepción detectada y luego volver a generar una excepción. Esta excepción debe ser manejada por otro bloque try-catch en el mismo método o cualquier otro método en la pila de llamadas. La excepción se propaga a lo largo de la función principal si no se detecta. 

Python3

function f(x)
    if(x < 5)
        throw(error())
    end
    return sqrt(x)
end
 
try
    println(f(9))
    println(f(1))
catch e
    println("Argument less than 5")
    throw(error())
end

Producción:

3.0
Argument less than 5
ERROR: LoadError: 
Stacktrace:
 [1] error() at ./error.jl:30
while loading /home/cg/root/945981/main.jl, in expression starting on line 13

Lanzamiento de error desde el bloque de captura

Python3

function f(x)
    if(x < 5)
        throw(error())
    end
    return sqrt(x)
end
 
try
    try
        println(f(9))
        println(f(1))
    catch e
        println("Argument less than 5")
        throw(error())
    end
catch e
    println("Second catch block")
end

Producción:

3.0
Argument less than 5
Second catch block

Prueba de captura de una línea

try sqrt(x) catch y end

Esto significa probar sqrt(x), y si se lanza una excepción, pásela a la variable y. Ahora bien, si se debe devolver el valor almacenado en y, entonces la captura debe ir seguida de un punto y coma.

try sqrt(x) catch; y end

Python3

try println(sqrt(-9)) catch; y end

Producción:

ERROR: LoadError: UndefVarError: y not defined
while loading /home/cg/root/945981/main.jl, in expression starting on line 1
Excepciones integradas

Julia proporciona algunas excepciones integradas, que son las siguientes:

Excepción Descripción
ArgumentError Esta excepción se produce cuando los parámetros de una llamada de función no coinciden con una firma válida.
BoundsError Esta excepción se lanza si el usuario intenta acceder a un índice de array más allá del rango del índice.
Excepción compuesta Esta excepción proporciona información sobre cada subtarea que genera una excepción dentro de una tarea.
Discrepancia de dimensión Esta excepción se lanza cuando los objetos llamados no tienen una dimensionalidad coincidente.
DivideError Esta excepción se lanza cuando el usuario intenta dividir por 0 (cero).
Error de dominio Esta excepción se lanza cuando el argumento de una función o constructor no se encuentra en el dominio válido.
EOFError Esta excepción se lanza cuando no quedan más datos para leer en un archivo.
Excepción de error Esta excepción se lanza para indicar un error genérico.
Error inexacto Esta excepción se lanza cuando el programa no puede convertir exactamente un valor particular al tipo T en un método.
InitError Esta excepción se produce cuando se produce un error al ejecutar la función __init__ de un módulo.
excepción de interrupción Esta excepción se lanza cuando un proceso se detiene desde la terminal usando CTRL+C.
InvalidStateException Esta excepción se produce cuando el programa se ejecuta en un estado no válido.
Error de clave Esta excepción se lanza cuando un usuario intenta acceder o eliminar un elemento inexistente de AbstractDict o Set.
Error de carga Esta excepción se produce si se produce un error al importar o utilizar un archivo.
Error de memoria insuficiente Esta excepción se lanza cuando un programa excede la memoria disponible del sistema.
ReadOnlyMemoryError Esta excepción se lanza cuando un programa intenta escribir una memoria que es de solo lectura.
RemoteException Esta excepción se lanza cuando la excepción de una computadora remota se lanza localmente. La excepción especifica el pid del trabajador y la excepción correspondiente.
Error de método Esta excepción se lanza cuando no existe un método con la firma de tipo requerida.
OverflowError Esta excepción se produce cuando el resultado de una expresión es demasiado grande para el tipo especificado y provoca un ajuste.
Meta.ParseError Esta excepción se genera cuando una expresión que se pasa a la función de análisis no se puede interpretar como una expresión de Julia válida.
Error del sistema Esta excepción se produce cuando falla una llamada al sistema.
Error de tecleado Esta excepción se produce cuando falla una aserción de tipo o se llama a una función intrínseca con un tipo de argumento incorrecto.
UndefRefError Esta excepción se lanza si un elemento o campo no está definido para el objeto especificado.
UndefVarError Esta excepción se produce cuando un símbolo no está definido en el ámbito actual.
StringIndexError Esta excepción se lanza cuando el usuario intenta acceder a un índice de string que excede la longitud de la string.

Publicación traducida automáticamente

Artículo escrito por Shreyasi_Chakraborty y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *