errors.New în Go

Creează o eroare simplă cu mesajul dat; folosită și pentru erori-santinelă (var ErrX = errors.New(...)).

Sintaxă
import "errors"

func New(text string) error

Ce face errors.New

În Go erorile sunt valori obișnuite de tip error, returnate ca ultim rezultat al funcției. errors.New("mesaj") creează cea mai simplă eroare: una care are doar textul. Apelantul verifică if err != nil și decide ce face.

Fiecare apel errors.New creează o eroare distinctă, chiar dacă textul este același. De aceea erorile pe care apelanții trebuie să le recunoască se declară o singură dată, ca variabile la nivel de pachet, cu nume care încep cu Err: var ErrNegasit = errors.New("nu a fost găsit"). Acestea se numesc erori-santinelă și se verifică cu errors.Is.

Pentru mesaje cu valori ("produsul 42 nu există") folosește fmt.Errorf, iar cu %w poți împacheta o eroare existentă păstrând-o recognoscibilă. Prin convenție, mesajele încep cu literă mică și nu se termină cu punct.

Parametri

Parametru Descriere
text Mesajul erorii, returnat de err.Error().

Ce returnează

O valoare error nouă, diferită de orice altă eroare.

Exemple

Exemplul 1: Funcție care returnează o eroare

package main

import (
	"errors"
	"fmt"
)

func imparte(a, b float64) (float64, error) {
	if b == 0 {
		return 0, errors.New("împărțire la zero")
	}
	return a / b, nil
}

func main() {
	for _, b := range []float64{4, 0} {
		rez, err := imparte(10, b)
		if err != nil {
			fmt.Println("Eroare:", err)
			continue
		}
		fmt.Println("Rezultat:", rez)
	}
}

Rezultat

Rezultat: 2.5
Eroare: împărțire la zero

Exemplul 2: Erori-santinelă recunoscute de apelant

Două apeluri errors.New cu același text dau erori diferite; de aceea santinela se creează o singură dată.

package main

import (
	"errors"
	"fmt"
)

var (
	ErrStocInsuficient = errors.New("stoc insuficient")
	ErrProdusNegasit   = errors.New("produs negăsit")
)

var stoc = map[string]int{"cafea": 3, "ceai": 10}

func cumpara(produs string, bucati int) error {
	n, ok := stoc[produs]
	if !ok {
		return ErrProdusNegasit
	}
	if n < bucati {
		return ErrStocInsuficient
	}
	stoc[produs] -= bucati
	return nil
}

func main() {
	for _, p := range []string{"ceai", "cafea", "zahăr"} {
		err := cumpara(p, 5)
		switch {
		case err == nil:
			fmt.Printf("%s: comandă plasată\n", p)
		case errors.Is(err, ErrStocInsuficient):
			fmt.Printf("%s: mai avem doar %d\n", p, stoc[p])
		case errors.Is(err, ErrProdusNegasit):
			fmt.Printf("%s: nu vindem acest produs\n", p)
		}
	}
	fmt.Println("Același text, erori diferite:", errors.New("x") == errors.New("x"))
}

Rezultat

ceai: comandă plasată
cafea: mai avem doar 3
zahăr: nu vindem acest produs
Același text, erori diferite: false

Greșeli frecvente

  • Compari mesajele erorilor (err.Error() == "stoc insuficient"). Textul se poate schimba; compară cu santinela folosind errors.Is.
  • Creezi santinela în interiorul funcției (return errors.New("negăsit")) și apoi încerci să o compari: fiecare apel dă altă eroare.
  • Ignori eroarea cu _. Dacă funcția poate eșua, verifică err != nil înainte să folosești rezultatul.

Comenzi înrudite

  • errors.Is: Verifică dacă eroarea err este target sau o conține, căutând prin toate erorile împachetate cu %w sau Join.
  • errors.As: Caută în lanțul de erori prima eroare de un anumit tip și o pune în target (un pointer), ca să-i citești câmpurile.
  • errors.Join: Unește mai multe erori într-una singură; mesajele apar pe linii separate, iar errors.Is/As le găsesc pe fiecare.
  • errors.Unwrap: Returnează eroarea împachetată direct în err (un singur nivel), sau nil dacă err nu împachetează nimic.