Custom Error Types
In this page:
type NameError struct {
Field type
}
func (e *NameError) Error() string {
return "message"
}
Defining a Custom Error Type
A custom error is just a struct with an Error() string method, which lets it carry additional structured fields beyond a plain message -- useful when calling code needs more context than text alone.
Example: Defining a Custom Error Type
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define a struct type named ValidationError
type ValidationError struct {
Field string
Msg string
}
// Define the method Error on type ValidationError
func (e *ValidationError) Error() string {
// Sprintf builds a formatted string instead of printing it
return fmt.Sprintf("%s: %s", e.Field, e.Msg)
}
// main is where the program starts running
func main() {
var err error = &ValidationError{Field: "age", Msg: "must be positive"}
// Print the values followed by a newline
fmt.Println(err)
}
Login to try C/C++/Java/PHP code in the editor
Returning a Custom Error
A function can return a custom error type through the standard error interface, so calling code that only cares whether it failed can treat it like any other error, while code that wants details can inspect it further.
Example: Returning a Custom Error
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define a struct type named OutOfStockError
type OutOfStockError struct {
Item string
}
// Define the method Error on type OutOfStockError
func (e *OutOfStockError) Error() string {
// Sprintf builds a formatted string instead of printing it
return fmt.Sprintf("%s is out of stock", e.Item)
}
// Define the function checkStock
func checkStock(item string, qty int) error {
// Check whether qty <= 0
if qty <= 0 {
// Send &OutOfStockError{Item: item} back to the caller
return &OutOfStockError{Item: item}
}
return nil
}
func main() {
if err := checkStock("widget", 0); err != nil {
fmt.Println(err)
}
}
Login to try C/C++/Java/PHP code in the editor
Extracting a Custom Error with errors.As
errors.As checks whether an error (or anything it wraps) matches a specific custom error type, and if so, populates a target variable with it -- letting calling code react to structured fields, not just a message string.
Example: Extracting a Custom Error with errors.As
// Every Go file belongs to a package; main builds an executable
package main
// Import the packages this program uses
import (
"errors"
"fmt"
)
// Define a struct type named OutOfStockError
type OutOfStockError struct {
Item string
}
// Define the method Error on type OutOfStockError
func (e *OutOfStockError) Error() string {
// Sprintf builds a formatted string instead of printing it
return fmt.Sprintf("%s is out of stock", e.Item)
}
// main is where the program starts running
func main() {
var err error = &OutOfStockError{Item: "widget"}
// Declare oosErr with the zero value of its type
var oosErr *OutOfStockError
// Check whether errors.As(err, &oosErr)
if errors.As(err, &oosErr) {
fmt.Println("out of stock item:", oosErr.Item)
}
}
Login to try C/C++/Java/PHP code in the editor
- Defining a custom error struct but forgetting to implement Error() string on it, so it doesn't actually satisfy the error interface.
- Using a value receiver for Error() but returning &MyError{} (a pointer) elsewhere inconsistently, causing type assertion mismatches.
- Storing only a string message in a custom error type when structured fields (like a status code) would let callers react programmatically.
- A custom error type is any struct that implements the Error() string method.
- Custom errors can carry structured data beyond a plain message, like an error code or the invalid value.
- Callers use errors.As to check for and extract a specific custom error type.
- Custom errors make failure handling more precise than parsing error message strings.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: