errors.AsType în Go

Erori (errors) Go 1.26

Varianta generică a lui errors.As: returnează direct prima eroare de tipul E din lanț și true dacă a găsit-o.

Sintaxă
func AsType[E error](err error) (E, bool)

Ce face errors.AsType

errors.AsType[*EroareValidare](err) face același lucru ca errors.As, dar fără variabila declarată dinainte și fără pointerul la ea. Tipul căutat se scrie între paranteze drepte, iar funcția returnează eroarea găsită și un bool.

Avantajul: compilatorul verifică tipul (trebuie să implementeze error), deci greșeala clasică a lui As, ținta transmisă fără &, nu mai este posibilă. Se potrivește natural cu forma if ev, ok := errors.AsType[*T](err); ok { ... }.

Parametri

Parametru Descriere
E Tipul de eroare căutat (parametru de tip), de exemplu *fs.PathError.
err Eroarea primită.

Ce returnează

Eroarea găsită, de tipul E, și true; altfel valoarea zero a lui E și false.

Exemple

Exemplul 1: Același caz ca la errors.As, mai scurt

package main

import (
	"errors"
	"fmt"
	"strconv"
)

type EroarePlata struct {
	Cod   int
	Suma  float64
}

func (e *EroarePlata) Error() string {
	return "plata de " + strconv.FormatFloat(e.Suma, 'f', 2, 64) + " lei a eșuat, cod " + strconv.Itoa(e.Cod)
}

func plateste(suma float64) error {
	return fmt.Errorf("comanda 2026-17: %w", &EroarePlata{Cod: 51, Suma: suma})
}

func main() {
	err := plateste(249.90)
	fmt.Println(err)

	if ep, ok := errors.AsType[*EroarePlata](err); ok {
		fmt.Println("Cod bancă:", ep.Cod)
		if ep.Cod == 51 {
			fmt.Println("Fonduri insuficiente, propune altă metodă de plată")
		}
	}
}

Rezultat

comanda 2026-17: plata de 249.90 lei a eșuat, cod 51
Cod bancă: 51
Fonduri insuficiente, propune altă metodă de plată

Exemplul 2: Mai multe tipuri verificate pe rând

package main

import (
	"errors"
	"fmt"
	"io/fs"
	"os"
	"strconv"
)

func descrie(err error) string {
	if pe, ok := errors.AsType[*fs.PathError](err); ok {
		return "problemă cu fișierul " + pe.Path
	}
	if ne, ok := errors.AsType[*strconv.NumError](err); ok {
		return "număr invalid: " + strconv.Quote(ne.Num)
	}
	return "eroare necunoscută: " + err.Error()
}

func main() {
	_, err1 := os.ReadFile("lipsa.txt")
	_, err2 := strconv.Atoi("doisprezece")
	err3 := errors.New("altceva")
	for _, err := range []error{err1, err2, err3} {
		fmt.Println(descrie(err))
	}
}

Rezultat

problemă cu fișierul lipsa.txt
număr invalid: "doisprezece"
eroare necunoscută: altceva

Greșeli frecvente

  • Scrii tipul fără steluță (errors.AsType[EroarePlata]) când metoda Error are receptor pointer. Codul nu compilează, pentru că EroarePlata nu implementează error; folosește *EroarePlata.
  • Folosești AsType într-un proiect cu versiune Go mai veche de 1.26 în go.mod: funcția nu există. Folosește errors.As.

Comenzi înrudite

  • 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.Is: Verifică dacă eroarea err este target sau o conține, căutând prin toate erorile împachetate cu %w sau Join.
  • errors.New: Creează o eroare simplă cu mesajul dat; folosită și pentru erori-santinelă (var ErrX = errors.New(…)).