A try .. rescue segítségével elkaphatod és kiértékelheted a blokkon belül keletkező hibákat.
Például:
try do
raise RuntimeError, "error"
rescue
e in RuntimeError -> :error
end
try kulcsszóval deklaráljuk.raise/1-et hívjuk.rescue részben mintát illesztünk a kiváltott hiba moduljának nevére
-> bal oldalán:
e a hibastruktúrára illeszkedik.in egy kulcsszó.RuntimeError az a modul, amelyre illesztünk, de illeszkedhetünk bármely hibamodulra, vagy a _ az összes hibára.Az így elkapott hibák (amelyeket néha „kivételeknek” is neveznek) struktúrák. A különböző hibastruktúráknak különböző kulcsaik vannak. A standard könyvtár „exceptions” szakaszában megtalálod az összes előre definiált hiba listáját.
# 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}
Hibák elkapása az Elixirben nagyon ritkán fordul elő. Az elkapott hibát általában naplózzuk, vagy elküldjük egy külső monitorozó szolgáltatásnak, majd újradobjuk. Ez azt jelenti, hogy általában nem foglalkozunk az adott hibastruktúra belső szerkezetével.
Az Exceptions fogalom leírja, hogyan definiálhatsz saját hibastruktúrákat.
Kerüld azokat a programozási mintákat, amelyek hibákkal vezérlik a logikai folyamatot. Ez anti-minta az Elixirben.
# 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
Ahogy az Elixir kezdő útmutatójában áll:
A te alkalmazásod dönti el, hogy egy hiba egy művelet végrehajtása során kivételes-e vagy sem. Ezért az Elixir nem kényszerít kivételeket a [...] függvényekre. Ehelyett a fejlesztőre bízza, hogy eldöntse, hogyan tovább.