Creare errori personalizzati
errors.New, fmt.Errorf ed errori sentinella
Creare errori personalizzati è una lezione Go Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Go Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Go Academy include 4 lezioni in totale.
Perché utilizzare tipi di errore personalizzati?
I tipi di errore personalizzati contengono dati strutturati oltre a un messaggio testuale, consentendo ai chiamanti di esaminare e gestire condizioni di errore specifiche:
package main
import "fmt"
// Custom error type carries extra context
type HTTPError struct {
StatusCode int
Message string
}
func (e *HTTPError) Error() string {
return fmt.Sprintf("HTTP %d: %s", e.StatusCode, e.Message)
}
func fetch(url string) error {
return &HTTPError{404, "page not found"}
}
func main() {
err := fetch("http://example.com")
fmt.Println(err) // HTTP 404: page not found
}Implementare l'interfaccia error
Qualsiasi tipo con un metodo Error() string soddisfa error:
package main
import "fmt"
type ValidationError struct {
Field string
Value interface{}
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("validation: field %q value %v — %s", e.Field, e.Value, e.Message)
}
func validateAge(age int) error {
if age < 0 || age > 150 {
return &ValidationError{"age", age, "must be between 0 and 150"}
}
return nil
}
func main() {
fmt.Println(validateAge(-5))
}Errori sentinella con errors.New
Gli errori sentinella sono variabili a livello di pacchetto per condizioni di errore note:
package main
import ("fmt"; "errors")
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrAlreadyExists = errors.New("already exists")
)
func getUser(id int) (string, error) {
if id != 1 { return "", ErrNotFound }
return "Alice", nil
}
func main() {
_, err := getUser(99)
if errors.Is(err, ErrNotFound) {
fmt.Println("user does not exist")
}
}fmt.Errorf con %w per il wrapping
fmt.Errorf con %w esegue il wrapping di un errore, preservando l'originale per errors.Is ed errors.As:
package main
import ("fmt"; "errors")
var ErrDatabase = errors.New("database error")
func queryDB() error {
return fmt.Errorf("queryDB: %w", ErrDatabase)
}
func main() {
err := queryDB()
fmt.Println(err) // queryDB: database error
fmt.Println(errors.Is(err, ErrDatabase)) // true — unwrapped
}Errore personalizzato con Unwrap
Implementi Unwrap() error nel tipo di errore personalizzato per partecipare alle catene di errori:
package main
import ("fmt"; "errors")
var ErrNotFound = errors.New("not found")
type QueryError struct {
Query string
Err error
}
func (e *QueryError) Error() string {
return fmt.Sprintf("query %q: %v", e.Query, e.Err)
}
func (e *QueryError) Unwrap() error { return e.Err }
func main() {
err := &QueryError{"SELECT *", ErrNotFound}
fmt.Println(err)
fmt.Println(errors.Is(err, ErrNotFound)) // true
}errors.Is — Controllo dell'identità
errors.Is percorre la catena degli errori cercando un errore uguale al valore di destinazione:
package main
import ("fmt"; "errors")
var ErrTimeout = errors.New("timeout")
func deepCall() error {
return fmt.Errorf("layer3: %w", fmt.Errorf("layer2: %w", ErrTimeout))
}
func main() {
err := deepCall()
fmt.Println(errors.Is(err, ErrTimeout)) // true — found deep in chain
}errors.As — Estrazione del tipo
errors.As trova nella catena il primo errore che corrisponde al tipo di destinazione e lo assegna:
package main
import ("fmt"; "errors")
type PermissionError struct{ User string }
func (e *PermissionError) Error() string { return "permission denied for " + e.User }
func action(user string) error {
return fmt.Errorf("action: %w", &PermissionError{user})
}
func main() {
err := action("bob")
var pe *PermissionError
if errors.As(err, &pe) {
fmt.Println("denied:", pe.User) // denied: bob
}
}Wrapping multiplo degli errori (Go 1.20+)
Go 1.20 ha aggiunto errors.Join e fmt.Errorf con più %w per unire gli errori:
package main
import ("fmt"; "errors")
func validate(name, email string) error {
var errs []error
if name == "" { errs = append(errs, errors.New("name required")) }
if email == "" { errs = append(errs, errors.New("email required")) }
return errors.Join(errs...)
}
func main() {
err := validate("", "")
fmt.Println(err)
// name required
// email required
}Convenzioni per i nomi dei tipi di errore
Convenzioni per le variabili e i tipi di errore in Go:
- Variabili di errore sentinella:
ErrXxx(ad esempioErrNotFound) - Tipi di errore personalizzati:
XxxError(ad esempioValidationError) - Una var a livello di pacchetto per gli errori sentinella, un tipo puntatore per gli errori con dati dettagliati
- Esporti gli elementi affinché i chiamanti possano utilizzarli con
errors.Is/errors.As
Quando utilizzare ciascun approccio
Scelta dell'approccio corretto per gli errori:
errors.New— semplice, senza dati aggiuntivi, per il controllo dell'identità di un errore sentinellafmt.Errorf— messaggio formattato con wrapping opzionale- Tipo personalizzato — quando il chiamante ha bisogno di dati strutturati (campi, codici)
errors.Join— per aggregare più errori di convalida
Verifica rapida
Quale funzione consente di estrarre un tipo di errore specifico da una catena di errori?
Riepilogo: errori personalizzati
Riepilogo:
- Implementi
Error() stringper creare tipi di errore personalizzati - Aggiunga
Unwrap() errorper partecipare alle catene di errori - Utilizzi
errors.Isper i controlli di identità ederrors.Asper l'estrazione del tipo - Errori sentinella:
ErrXxx; tipi personalizzati:XxxError errors.Joinaggrega più errori (Go 1.20+)
Domande Frequenti
La lezione «Creare errori personalizzati» è gratuita?
Sì — il testo completo di «Creare errori personalizzati» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Go Academy, passa a CoddyKit PRO. Il corso Go Academy include 4 lezioni in totale.
Cosa imparerò in «Creare errori personalizzati»?
errors.New, fmt.Errorf ed errori sentinella Eserciti Go Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Go Academy?
Non è richiesta alcuna esperienza precedente. Go Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Creare errori personalizzati»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Go Academy?
Sì. Ogni lezione Go Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- L'interfaccia error
- Creare errori personalizzati
- Wrapping e unwrap degli errori
- panic, recover e defer