2 · Model and validate · 25 MIN
Errors and input boundaries
Expected input failures should be returned to the caller.
strconv.Atoi can fail for text that is not a valid int. Check that error before using the parsed value, then apply domain rules such as nonnegative quantity. Wrapping the error with %w preserves its cause for errors.Is or errors.As when callers need to distinguish failures. The program prints a friendly decision instead of ignoring a failure or panicking. Domain validation and parsing are separate operations: a correctly parsed negative integer can still be invalid for a quantity.
Validate syntax first, then the permitted range.
Read the example
package main
import ("fmt"; "strconv")
func quantity(raw string) (int, error) {
n, err := strconv.Atoi(raw)
if err != nil { return 0, fmt.Errorf("invalid quantity: %w", err) }
if n < 0 { return 0, fmt.Errorf("quantity must be nonnegative") }
return n, nil
}
func main() { for _, raw := range []string{"3","-1","many"} { n, err := quantity(raw); if err != nil { fmt.Println("invalid") } else { fmt.Println(n) } } }Check the expected output
3 invalid invalid
Your challenge
Extend quantity with a maximum of 1000 and return a distinct domain error when exceeded.
Solution cost: O(m) parsing for an m-character input. time · Account for collection storage separately from the returned result. space
Common trap
Using n after discarding err turns invalid input into an apparently valid zero.
Study the project implementation
package main
import ("fmt"; "strconv")
func quantity(raw string) (int, error) {
n, err := strconv.Atoi(raw)
if err != nil { return 0, fmt.Errorf("invalid quantity: %w", err) }
if n < 0 { return 0, fmt.Errorf("quantity must be nonnegative") }
return n, nil
}
func main() { for _, raw := range []string{"3","-1","many"} { n, err := quantity(raw); if err != nil { fmt.Println("invalid") } else { fmt.Println(n) } } }Further reading: Official documentation
Next lesson: Goroutines and channel ownership →