Oprettelse af brugerdefinerede fejl
errors.New, fmt.Errorf og sentinel-fejl
Oprettelse af brugerdefinerede fejl er en gratis Go Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Go Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Go Academy-kurset indeholder 4 lektioner i alt.
Hvorfor bruger man tilpassede fejltyper?
Tilpassede fejltyper indeholder strukturerede data ud over en tekstmeddelelse, så kaldere kan undersøge og reagere på bestemte fejltilstande:
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
}Implementering af error-grænsefladen
Enhver type med en Error() string-metode opfylder 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))
}Sentinelfejl med errors.New
Sentinelfejl er variabler på pakkeniveau for velkendte fejltilstande:
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 med %w til indpakning
fmt.Errorf med %w pakker en fejl ind og bevarer den oprindelige fejl til errors.Is og 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
}Tilpasset fejl med Unwrap
Implementér Unwrap() error på din tilpassede fejltype, så den kan indgå i fejlkæder:
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 — Identitetskontrol
errors.Is gennemgår fejlkæden for at finde en fejl, der er lig med målet:
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 — Typeudtrækning
errors.As finder den første fejl i kæden, der svarer til en måltype, og tildeler den:
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
}
}Indpakning af flere fejl (Go 1.20+)
Go 1.20 tilføjede errors.Join og fmt.Errorf med flere %w til sammenføjning af fejl:
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
}Navnekonventioner for fejltyper
Konventioner for fejlvariabler og -typer i Go:
- Sentinelfejlvariabler:
ErrXxx(f.eks.ErrNotFound) - Tilpassede fejltyper:
XxxError(f.eks.ValidationError) - Variabel på pakkeniveau til sentinel-fejl, pointertype til fejl med mange oplysninger
- Eksportér dem, så kaldere kan bruge dem i
errors.Is/errors.As
Hvornår skal du bruge de forskellige metoder?
Sådan vælger du den rette tilgang til fejl:
errors.New— enkel fejl uden ekstra data og med kontrol af sentinel-identitetfmt.Errorf— formateret meddelelse med valgfri indpakning- Tilpasset type — når kaldere har brug for strukturerede data (felter, koder)
errors.Join— samler flere valideringsfejl
Hurtigt tjek
Hvilken funktion gør det muligt at udtrække en bestemt fejltype fra en fejlkæde?
Opsamling: Tilpassede fejl
Opsummering:
- Implementér
Error() stringfor at oprette tilpassede fejltyper - Tilføj
Unwrap() errorfor at indgå i fejlkæder - Brug
errors.Istil identitetskontrol ogerrors.Astil typeudtrækning - Sentinelfejl:
ErrXxx; tilpassede typer:XxxError errors.Joinsamler flere fejl (Go 1.20+)
Lær Go med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 51
- Lektioner
- 203
Ofte stillede spørgsmål
Er lektionen “Oprettelse af brugerdefinerede fejl” gratis?
Ja — alle 3 lektioner i læringssporet Go Academy, inklusive “Oprettelse af brugerdefinerede fejl”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Go Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Oprettelse af brugerdefinerede fejl”?
errors.New, fmt.Errorf og sentinel-fejl Du øver dig i Go Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Go Academy?
Der kræves ingen tidligere erfaring. Go Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “Oprettelse af brugerdefinerede fejl”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Go Academy-lektion?
Ja. Alle Go Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- interfacet error
- Oprettelse af brugerdefinerede fejl
- Indpakning og udpakning af fejl
- panic, recover og defer