go 42 lines · 7 steps

Parsing timeout config in Go

A small config loader turns raw environment strings into validated durations with helpful errors and sane defaults.

Explained by highlit
1package config
2 
3import (
4 "fmt"
5 "time"
6)
7 
8type Timeouts struct {
9 Read time.Duration
10 Write time.Duration
11 Shutdown time.Duration
12}
13 
14func parseDuration(name, raw string, fallback time.Duration) (time.Duration, error) {
15 if raw == "" {
16 return fallback, nil
17 }
18 d, err := time.ParseDuration(raw)
19 if err != nil {
20 return 0, fmt.Errorf("config %q: invalid duration %q: %w", name, raw, err)
21 }
22 if d < 0 {
23 return 0, fmt.Errorf("config %q: duration must not be negative: %s", name, d)
24 }
25 return d, nil
26}
27 
28func LoadTimeouts(env map[string]string) (Timeouts, error) {
29 var t Timeouts
30 var err error
31 
32 if t.Read, err = parseDuration("READ_TIMEOUT", env["READ_TIMEOUT"], 15*time.Second); err != nil {
33 return Timeouts{}, err
34 }
35 if t.Write, err = parseDuration("WRITE_TIMEOUT", env["WRITE_TIMEOUT"], 15*time.Second); err != nil {
36 return Timeouts{}, err
37 }
38 if t.Shutdown, err = parseDuration("SHUTDOWN_TIMEOUT", env["SHUTDOWN_TIMEOUT"], 30*time.Second); err != nil {
39 return Timeouts{}, err
40 }
41 return t, nil
42}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Centralizing parsing in one helper keeps validation and error formatting consistent across every field.
  2. 2Wrapping errors with %w preserves the underlying cause while adding which config key failed.
  3. 3Returning a zero-value struct alongside the error forces callers to check err before using the result.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Parsing timeout config in Go — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code