error
típus
A nyelv rendelkezik egy előre definiált error
interface típussal:
Ez a szokásos, hibajelzésre használatos interface olyan módon, hogy a nil
érték jelzi, ha nincs hiba. Hiba esetén pedig az érték (legalább) a hibaüzenet kiírására alkalmas Error
függvényt biztosítja.
További konvenció, hogy az Error
string tartalmazza a csomag nevét, ahol a hiba keletkezett, pl.: image: processing error.
A Go nyelvben a legtöbb hibát a függvények visszatérési értékével jelzik. Ezt megkönnyíti, hogy a függvényeknek több visszatérési értéke is lehet, így az eredményt és az esetleges hibajelzést egyszerre vissza lehet adni.
Ebben az esetben is az error
típus a szokásos hibajelzésre. A hívó oldalon a hiba kezelése például így nézhet ki:
Panic
és recover
Az olyan súlyos hibák kezelésére, amikor a program nem folytatható, kínálja a nyelv a panic
és recover
függvényeket.
A panic
beépített függvény futásidejű hibát generál. Egyetlen, tetszőleges típusú paramétert vár (ez a gyakorlatban többnyire egy string, esetleg egy error
típusú érték), ez lesz a hibaüzenet.
Ez a függvény használható akkor is, ha valamilyen lehetetlennek tűnő esemény történt, például véget ért egy (elvileg) végtelen ciklus. Ezt a fordító is támogatja: ha a függvény végén panic
áll, a return
elhagyható.
Nemcsak a felhasználó hívhatja meg a panic
függvényt, ez implicit hívódik meg például tömb túlindexelésekor, típushibáknál vagy egyéb futásidejű hibáknál is.
A panic
híváskor azonnal megszakítja a függvény futását, és elkezdi kiüríteni az aktuális gorutin vermét, esetleg végrehajtva a defer
kulcsszóval ellátott függvényeket (ld. alább). Ha a hibát a program sehol sem kezeli, a verem kiürül, a program futása leáll, és kiírja a panic
paraméterét a képernyőre.
A panic
gyakori használatát a nyelv készítői nem tartják szerencsés megoldásnak. Ha egy felmerülő hiba kezelésére, elkerülésére és a program további helyes futásának biztosítására lehetőség van helyben, akkor felesleges kockáztatni a teljes program leállását (vagy a könyvtárunk felhasználóit nagy mennyiségű hibakezelő kód írására kényszeríteni).
A recover
szintén beépített függvény, paramétere nincs. Hívásakor megállítja a panic
terjedését, hogy a hibát kezelni lehessen. Visszatérési értéke a hibaérték: interface{}
típusú. ha ez az érték nil
, akkor nem történt hiba.
Ahhoz, hogy a panic
végrehajtsa a recover
-t tartalmazó kódot, a defer
kulcsszót kell használni. A defer
utáni függvény- vagy metódushívás nem azonnal hajtódik végre, hanem közvetlenül azelőtt, hogy az őt tartalmazó függvény visszatérne. Ez akkor is igaz, ha a panic
kényszeríti visszatérésre a függvényt, így ez az egyetlen módja annak, hogy a panic
-ot okozó hibát kezeljük.
A fenti példában a server
függvény több dolgozót indít el párhuzamosan. Ha bármelyik dolgozóban hiba lép fel, hibaüzenetet ír ki, és a dolgozó leáll anélkül, hogy a teljes program kilépne.
Természetesen a defer
függvényben lehetőségünk van a hibát továbbdobni vagy másik hibát kiváltani a panic
explicit hívásával. Illetve ha egy ilyen kód egy függvényhívásában újabb panic
történik, akkor az "új" hiba a korábbi hívási láncon terjed tovább.
Érdekes tulajdonsága a defer
függvényeknek, hogy mivel a visszatérés előtt mindig lefutnak (nem csak panic
esetén), ezért a nevesített visszatérési értékeket módosíthatjuk egy ilyen függvényből. Ez hasznos lehet hibakezelésnél is (pl. egy részlegesen elkészült visszatérési értéket alapértékre állíthatunk), de általánosabban is használható.