Tracce
/
Elixir
Elixir
/
Programma
/
Try/Rescue
Tr

Try/Rescue in Elixir

1 esercizio

Informazioni su Try/Rescue

try .. rescue può essere usato per catturare e valutare gli errori che vengono sollevati all'interno di un blocco.

Per esempio:

try do
  raise RuntimeError, "error"
rescue
  e in RuntimeError -> :error
end
  • Riga 1, il blocco viene dichiarato con try.
  • Riga 2, qui va inserita la chiamata di funzione che potrebbe generare un errore, in questo caso stiamo chiamando raise/1.
  • Riga 4, nella sezione rescue, facciamo pattern matching sul nome del Modulo dell'errore sollevato
    • sul lato sinistro di ->:
      • e corrisponde alla struct dell'errore.
      • in è una parola chiave.
      • RuntimeError è il modulo da confrontare, ma puoi confrontarlo con qualsiasi modulo di errore, oppure _ per tutti gli errori.
    • sul lato destro:
      • le istruzioni da eseguire se l'errore corrisponde.

Struct di errore

Gli errori (a volte chiamati anche «eccezioni») che intercetti in questo modo sono struct. Struct di errore diverse hanno chiavi diverse. Nella sezione «eccezioni» della libreria standard puoi trovare un elenco di tutti gli errori predefiniti.

# 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}

In Elixir, gli errori si intercettano molto raramente. Di solito l'errore intercettato viene registrato nei log o inviato a un servizio di monitoraggio esterno, per poi essere risollevato. Questo significa che di solito non ci interessa la struttura interna della struct di errore specifica.

Il concetto Eccezioni descrive come definire struct di errore personalizzate.

Evita gli anti-pattern

  • Evita i pattern di programmazione che usano gli errori per controllare il flusso logico. In Elixir questo è un anti-pattern.

    # 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
    

Sollevare o non sollevare, questo è il problema

Come si legge nella guida introduttiva di Elixir:

Sta alla tua applicazione decidere se un errore mentre [si compie un'azione] è eccezionale o no. Ecco perché Elixir non impone eccezioni alle [...] funzioni. Lascia invece allo sviluppatore scegliere il modo migliore per procedere.

Modifica tramite GitHub Il collegamento si apre in una nuova finestra o scheda

Impara Try/Rescue