Concept
Fail loud
Errors you see on day one are cheap.
Throw when something is wrong. Never catch-and-ignore. Never fall back to a hidden default. Never silence the type system without comment.
Forbidden
// ❌ Silent catch
try { risky(); } catch {}
// ❌ Silent fallback — now you never discover config drift
const bet = config.defaultBet ?? 1;
// ❌ Type lie without reason
const x = response as any; Allowed
// ✅ Throw with who/what/where
if (!config.defaultBet) {
throw new Error('[composition] missing defaultBet — set in src/config/gameConfig.ts');
}
// ✅ Explicit, explained escape hatch
// The spine-pixi-v8 types lag the runtime by a version.
// Remove once https://github.com/.../issue-123 lands.
const spine = instance as unknown as SpineWithMissingField; Why
Silent failures produce a worst-case pattern: the code looks fine in PR review, passes tests, ships — and starts misbehaving in week four, when the diff is cold and the person who wrote it has moved on. A thrown error in week one is a commit away from a fix. A silent divergence in week four is an incident.