what is it?

go code uses error values to indicate an abnormal state

  • default or “zero” value of an error is nil
  • typically returned as the last argument in a function
  • error messages are usually written in lower case and don’t end in punctuation

error type

the error type is predeclared in the uniververse block, meaning you don’t have to import anything to use it

how it looks in the code

type error interface {
    Error() string
}
 
// errorString is a trivial implementation of error.
type errorString struct {
    s string
}
 
func (e *errorString) Error() string {
    return e.s
}
 
// New returns an error that formats as the given text.
func New(text string) error {
    return &errorString{text}
}
 

usage

func Sqrt(f float64) (float64, error) {
    if f < 0 {
        return 0, errors.New("math: square root of negative number")
    }
    // implementation
}
 
f, err := Sqrt(-1)
if err != nil {
    fmt.Println(err)
}

The fmt package formats an error value by calling its Error() string method

fmt.Errorf uses errors.New to return an error

if f < 0 {
    return 0, fmt.Errorf("math: square root of negative number %g", f)
}

own error implementation

instead of using errors.errorString, we can define our own implementation

type NegativeSqrtError float64
 
func (f NegativeSqrtError) Error() string {
    return fmt.Sprintf("math: square root of negative number %g", float64(f))
}
 
// add extra functionality
 
func (f NegativeSqrtError) Poep() string  {
    return "Poep"
}

use a type assertion to check for a NegativeSqrtError and handle it specially

_, err := Sqrt(-1)
if err != nil {
    fmt.Println(err) // prints "math: square root of negative number -1"
    // using type assertion to check for NegativeSqrtError and then handling it separately
    if ferr, ok := err.(NegativeSqrtError); ok {
        fmt.Println(ferr.Poep())
    }
}