Lecții din modul (5/5)
Erori: modelul `if err != nil`
În Go, erorile sunt valori, nu excepții. O funcție care poate fail returnează eroarea ca ultima valoare, iar apelantul o verifică în mod explicit. Este explicit, previzibil, ușor de testat - prețul este putin mai multa verbozitate.
Interfața error
error este o interfață mică încorporată în limba:
type error interface {
Error() string
}Orice tip care implementează Error() string este un error.
Modelul fundamental
v, err := operazione()
if err != nil {
// gestisci o propaga
return err
}
// usa vVeți vedea asta de mii de ori: este codul idiomatic pentru fiecare apel falibil. Nu vă simțiți vinovat de repetare - este o caracteristică, nu un bug.
Erori de construcție: errors.New și fmt.Errorf
import (
"errors"
"fmt"
)
err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)fmt.Errorf este perfect atunci când doriți să includeți variabile în mesaj.
Încheiere cu %w
Pentru a propaga o eroare la adăugarea contextului FĂRĂ a pierde originalul:
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("config: %w", err)
}%w „încheie” eroarea originală, care poate fi recuperată ulterior cu
errors.Is (egalitatea pentru santinele) sau errors.As (pentru tipul de beton):
if errors.Is(err, os.ErrNotExist) {
// file inesistente, gestione speciale
}Erori santinelă
Acestea sunt erori exportate ca variabile, utilizate pentru comparații cu errors.Is:
var ErrNotFound = errors.New("non trovato")
func find(id int) (Item, error) {
// ...
return Item{}, ErrNotFound
}
// chiamante:
if errors.Is(err, ErrNotFound) { ... }panic și recover (previzualizare)
panic există în Go, dar este rezervat pentru erori nerecuperabile (de exemplu, erori,
invarianți încălcați), nu pentru fluxul de control normal. Vom intra mai adânc
modulul Funcții cu defer/recover. Deocamdată: nu-l folosi pe loc
a modelului if err != nil.
Încearcă
Gestionați eroarea de la strconv.Atoi: dacă err != nil, imprimați-o și returnați-o; altfel tipăriți n.
Afișează indiciu
Modelul canonic: verificați `err != nil`, log/return, apoi utilizați `n`.
Soluție disponibilă după 3 încercări
Implementați safeDiv: dacă b == 0 returnează 0 și un errors.New('divisione per zero'); în caz contrar a/b și nul.
Afișează indiciu
Verificați `b == 0` ÎNAINTE de împărțire pentru a evita panica în timpul rulării.
Soluție disponibilă după 3 încercări
Care este modelul idiomatic pentru a gestiona o eroare în Go?
v, err := f()
// poi?Recapitulare
erroreste o interfață cu o singură metodăError() string.- Model canonic:
v, err := f(); if err != nil { return err }. - Creați erori cu
errors.New(msg)saufmt.Errorf("ctx: %w", err). - Folosiți
%wpentru împachetare șierrors.Is/errors.Aspentru a inspecta lanțul. panicnumai pentru erori irecuperabile, NU pentru fluxul de control normal.