Tracks
/
Elixir
Elixir
/
Temario
/
Try/Rescue
Tr

Try/Rescue en Elixir

1 ejercicio

Acerca de Try/Rescue

try .. rescue se puede usar para capturar y evaluar los errores que se lanzan dentro de un bloque.

Por ejemplo:

try do
  raise RuntimeError, "error"
rescue
  e in RuntimeError -> :error
end
  • Línea 1, el bloque se declara con try.
  • Línea 2, aquí se coloca la llamada a la función que puede generar un error; en este caso, estamos llamando a raise/1.
  • Línea 4, en la sección rescue, hacemos coincidencia de patrones sobre el nombre del módulo del error lanzado
    • en el lado izquierdo de ->:
      • e se asigna a la estructura del error.
      • in es una palabra clave.
      • RuntimeError es el módulo con el que se hace coincidencia, pero puedes hacer coincidencia con cualquier módulo de error, o _ con todos los errores.
    • en el lado derecho:
      • las instrucciones que se ejecutan si el error coincide.

Estructuras de error

Los errores (a veces también llamados «excepciones») que rescatas de esta manera son estructuras. Las distintas estructuras de error tienen distintas claves. En la sección «exceptions» de la biblioteca estándar puedes encontrar una lista de todos los errores predefinidos.

# ArithmeticError caused by division by zero
%ArithmeticError{message: "bad argument in arithmetic expression"}

# Protocol.UndefinedError caused by passing `nil` to `Enum.count/1`
%Protocol.UndefinedError{description: "", protocol: Enumerable, value: nil}

En Elixir, rescatar errores se hace muy pocas veces. Por lo general, el error rescatado se registra o se envía a un servicio externo de monitoreo, y luego se vuelve a lanzar. Esto significa que por lo general no nos importa la estructura interna del error específico.

El concepto de excepciones describe cómo definir tus propias estructuras de error.

Evita los antipatrones

  • Evita los patrones de programación que usan errores para controlar el flujo lógico. Ese es un antipatrón en Elixir.

    # Avoid using errors for control-flow.
    try do
      {:ok, value} = MyModule.janky_function()
      "All good! #{value}."
    rescue
      e in RuntimeError ->
        reason = e.message
        "Uh oh! #{reason}."
    end
    
    # Rather, use control-flow structures for control-flow.
    case MyModule.janky_function() do
      {:ok, value} -> "All good! #{value}."
      {:error, reason} -> "Uh oh! #{reason}."
    end
    

Lanzar o no lanzar, esa es la cuestión

Como está escrito en la guía de introducción de Elixir:

Depende de tu aplicación decidir si un error al [realizar una acción] es excepcional o no. Por eso Elixir no impone excepciones a las funciones [...]. En cambio, deja que el desarrollador elija la mejor manera de proceder.

Editar en GitHub El enlace se abre en una ventana o pestaña nueva

Aprende Try/Rescue