Returning errors
- Go course
- Beginner
- Lesson 84/90
- 4 min
Learn to return errors with errors.New and fmt.Errorf.
Returning errors
Use errors.New for simple errors and fmt.Errorf for formatted messages and context. Errors the caller can compare against are defined as package-level variables (sentinel errors):
var ErrBulunamadi = errors.New("kayıt bulunamadı")
func bul(id int) (string, error) {
if id != 1 {
return "", fmt.Errorf("kullanıcı %d: %w", id, ErrBulunamadi)
}
return "Ada", nil
}Error messages start with a lower-case letter and don't end with a period, because they are used by appending to other messages.
Adding context to errors
As an error is passed upward, each layer adds what it was doing; the result is a readable chain:
// repository: kayıt bulunamadı
// service: kullanıcı 7: kayıt bulunamadı
// handler: profil yüklenemedi: kullanıcı 7: kayıt bulunamadıBoth logging and returning the same error leads to duplicate log lines; either handle it or add context and pass it on.
Practice Find a user
Write ErrBulunamadi and the bul(id int) (string, error) function above. Print the results of bul(1) and bul(7) on separate lines (fmt.Println(bul(...))).
Starter code
package main
import (
"errors"
"fmt"
)
func main() {
// buraya yaz
}Sample solution
package main
import (
"errors"
"fmt"
)
var ErrBulunamadi = errors.New("kayıt bulunamadı")
func bul(id int) (string, error) {
if id != 1 {
return "", fmt.Errorf("kullanıcı %d: %w", id, ErrBulunamadi)
}
return "Ada", nil
}
func main() {
fmt.Println(bul(1))
fmt.Println(bul(7))
}Expected output
Ada <nil> kullanıcı 7: kayıt bulunamadı
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 When there is an error, what should the other return values be?
- Anything
- Their zero values ("", 0, nil) Correct answer
- The last valid value
- -1
Explanation: Convention: when there is an error the other values aren't trusted and zero values are returned; the caller checks the error first.
2 Wrap with context
return "", fmt.Errorf("kullanıcı %d: ____", id, ErrBulunamadi)
return "", fmt.Errorf("kullanıcı %d: %w", id, ErrBulunamadi)
Explanation: %w wraps the error; the caller can find the original with errors.Is.
3 Tool and use
| Term | Meaning |
|---|---|
errors.New |
A simple error |
fmt.Errorf + %w |
An error with context |
var ErrX = ... |
A comparable error |
return "", err |
Zero value + error |