Files
go-kata/19-defer-cleanup-chain/README.md
2026-01-04 20:40:07 +01:00

2.1 KiB
Raw Blame History

Kata 19: The Cleanup Chain (defer + LIFO + Error Preservation)

Target Idioms: defer Discipline, Named Returns, Error Composition (errors.Join), Close/Rollback Ordering
Difficulty: 🟡 Intermediate

🧠 The "Why"

defer is easy to misuse:

  • deferring in loops (resource spikes),
  • ignoring Close() / Rollback() errors,
  • losing the original failure when cleanup also fails,
  • wrong cleanup ordering (commit then rollback nonsense).

Idiomatic Go keeps cleanup local, ordered, and preserves important errors.

🎯 The Scenario

You implement BackupDatabase:

  • open output file
  • connect DB
  • begin transaction
  • stream rows to file
  • commit If anything fails, you must close/rollback what was already acquired.

🛠 The Challenge

Implement:

  • func BackupDatabase(ctx context.Context, dbURL, filename string) (err error)

Use mock interfaces for DB + Tx + Rows if you want (recommended).

1. Functional Requirements

  • Open file for writing.
  • Connect to DB.
  • Begin Tx.
  • Write data (simulate streaming).
  • Commit on success.
  • On failure: rollback + close resources in correct order.

2. The "Idiomatic" Constraints (Pass/Fail Criteria)

  • Defer cleanup immediately after acquisition.
  • No manual cleanup paths except by controlling flags (e.g., committed bool) used by deferred funcs.
  • Preserve both errors: if main operation fails and cleanup fails too, return a combined error (errors.Join).
  • Named return err so defers can amend it safely.
  • No defer-in-loop for per-row resources: if your mock has per-row closers, show the correct pattern.

🧪 Self-Correction (Test Yourself)

  1. Tx Begin Fails

    • Make Begin() error.
    • Pass: file + db connection still close.
  2. Commit Fails + Close Fails

    • Make Commit() return error and also make file.Close() return error.
    • Pass: returned error clearly contains both (use errors.Join).
  3. No FD Leak

    • Run 1000 times.
    • Pass: file descriptors dont grow.

📚 Resources