Go is vanaf het begin gebouwd rond het expliciete retourneren van fouten in plaats van uitzonderingen. Dit stelt ontwikkelaars in staat om voorspelbare code te schrijven en te voorkomen dat ze onzichtbare valkuilen tegenkomen die typisch zijn voor try/catch-constructies van andere talen (zoals Java of C++). Een fout in Go is een interface die de Error()-methode implementeert, wat het mogelijk maakt om zowel eenvoudige als samengestelde/omhulde fouten met context te creëren.
Problemen ontstaan bij onjuiste foutafhandeling (bijvoorbeeld als ze worden genegeerd via _ of niet worden omhulld met extra informatie voor debugging) of het maken van "magische" fouten die niet voldoen aan de error-interface. Het is ook belangrijk om fouten terug te geven uit openbare functies en ze bij elke aanroep te controleren.
Oplossing — gebruik standaardbenaderingen:
Voorbeeldcode:
import ( "errors" "fmt" ) type NotFoundError struct { Resource string } func (e *NotFoundError) Error() string { return fmt.Sprintf("%s niet gevonden", e.Resource) } func GetUser(id int) (string, error) { if id != 1 { return "", &NotFoundError{"User"} } return "Steve", nil } func main() { user, err := GetUser(2) if err != nil { if nfe, ok := err.(*NotFoundError); ok { fmt.Println(nfe.Resource, "probleem") } else { fmt.Println("fout:", err) } } fmt.Println("gebruiker:", user) }
Belangrijke kenmerken:
Kun je bij het verwerken van een fout vergelijken met ==, of moet je speciale methodes gebruiken?
Het is beter om altijd errors.Is() te gebruiken voor vergelijking met foutomhulsel, anders kan de vergelijking met == niet werken bij het hebben van een omhulsel van de fout.
if errors.Is(err, os.ErrNotExist) { // verwerking van ontbrekend bestand }
Is het verplicht om een type-structuur te implementeren voor een aangepaste fout, of is het voldoende om errors.New("...") te gebruiken?
Als alleen de fouttekst nodig is, is errors.New() voldoende. Als het belangrijk is om de context te behouden (bijvoorbeeld de naam van de hulpbron), is het beter om een struct te definiëren met de Error()-methode.
Hoe moet je een fout correct retourneren in het geval van een succesvolle functie-uitvoering?
Bij succes moet je altijd een nil-fout retourneren.
return result, nil
Negatieve case
Een ontwikkelaar schrijft een functie die een fout retourneert zonder uitleg (gewoon errors.New("fail")). Bij het analyseren van logs is het niet mogelijk om de oorzaak vast te stellen.
Voordelen:
Nadelen:
Positieve case
Een ontwikkelaar definieert een aangepaste typefout NotFoundError en retourneert deze met een gedetailleerde beschrijving.
Voordelen:
Nadelen: