Challenge 3 - Error handling
- Go course
- Beginner
- Lesson 89/90
- 8 min
Write a function returning an error and calling code.
Challenge: a safe order
You will apply error handling. The function siparisVer(stok map[string]int, urun string, adet int) error checks three rules:
- if the quantity is below 1,
ErrGecersizAdet - if the product isn't in stock,
ErrUrunYok - if stock is insufficient,
fmt.Errorf("%s için yalnızca %d adet var: %w", urun, n, ErrYetersizStok)
If there is no error it deducts from stock and returns nil.
Plan
1) Define the three sentinel errors with errors.New in a var (...) block. 2) Check the quantity first, then the product's existence (n, ok := stok[urun]), then sufficiency; return early in each case. 3) If all pass, do stok[urun] -= adet and return nil. Order matters: cheap and general checks first.
Practice Order function
Write the function and the errors following the plan. For stok := map[string]int{"kalem": 3}, place the orders ("kalem", 2), ("kalem", 5) and ("silgi", 1) in turn; print each error (including nil) on its own line, and finally the result of errors.Is(err2, ErrYetersizStok).
Starter code
package main
import (
"errors"
"fmt"
)
func main() {
// buraya yaz
}Sample solution
package main
import (
"errors"
"fmt"
)
var (
ErrGecersizAdet = errors.New("geçersiz adet")
ErrUrunYok = errors.New("ürün yok")
ErrYetersizStok = errors.New("yetersiz stok")
)
func siparisVer(stok map[string]int, urun string, adet int) error {
if adet < 1 {
return ErrGecersizAdet
}
n, ok := stok[urun]
if !ok {
return ErrUrunYok
}
if adet > n {
return fmt.Errorf("%s için yalnızca %d adet var: %w", urun, n, ErrYetersizStok)
}
stok[urun] -= adet
return nil
}
func main() {
stok := map[string]int{"kalem": 3}
err1 := siparisVer(stok, "kalem", 2)
err2 := siparisVer(stok, "kalem", 5)
err3 := siparisVer(stok, "silgi", 1)
fmt.Println(err1)
fmt.Println(err2)
fmt.Println(err3)
fmt.Println(errors.Is(err2, ErrYetersizStok))
}Expected output
<nil> kalem için yalnızca 1 adet var: yetersiz stok ürün yok true
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 How does the caller recognize the "insufficient stock" case?
- err.Error() == "yetersiz stok"
- err != nil
- errors.Is(err, ErrYetersizStok) Correct answer
- err == ErrYetersizStok
Explanation: Because the error is wrapped with %w, == fails; errors.Is finds ErrYetersizStok in the chain.
2 Existence check
n, ____ := stok[urun]
if !ok {
return ErrUrunYok
}
n, ok := stok[urun]
if !ok {
return ErrUrunYok
}
Explanation: The comma-ok form says whether the product is in the map.
3 Order and result (kalem: 3)
| Term | Meaning |
|---|---|
kalem, 2 |
nil, stock 1 |
kalem, 0 |
ErrGecersizAdet |
silgi, 1 |
ErrUrunYok |
kalem, 9 |
ErrYetersizStok (wrapped) |