Rules Hub
Code Ruleset
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Cache reads/writes must degrade gracefully, not crash the request
Isolate cache get/set/parse in their own try/catch so a cache outage or corrupt entry falls back to a fresh fetch with a warning instead of failing the whole operation.
Bad example
| 1 | async function fetchWithCache<T>(key: string, ttl: number, fetcher: () => Promise<T>): Promise<T> { |
| 2 | const cached = await cache.get(key); // cache outage -> throws |
| 3 | if (cached) return JSON.parse(cached) as T; // corrupt entry -> throws |
| 4 | const data = await fetcher(); |
| 5 | await cache.set(key, JSON.stringify(data), ttl); // write failure -> throws |
| 6 | return data; |
| 7 | } |
Explanation (EN)
An optional cache outage should not convert a healthy source into a failed request.
Objašnjenje (HR)
Ispad neobaveznog cachea ne bi trebao pretvoriti dostupan izvor podataka u neuspješan zahtjev.
Good example
| 1 | async function fetchWithCache<T>(key: string, ttl: number, fetcher: () => Promise<T>, parse: (value: unknown) => T): Promise<T> { |
| 2 | try { |
| 3 | const cached = await cache.get(key); |
| 4 | if (cached != null) return parse(JSON.parse(cached)); |
| 5 | } catch { |
| 6 | logger.warn("Optional cache read or validation failed"); |
| 7 | } |
| 8 | const data = await fetcher(); |
| 9 | try { |
| 10 | const encoded = JSON.stringify(data); |
| 11 | if (encoded !== undefined) await cache.set(key, encoded, ttl); |
| 12 | } catch { |
| 13 | logger.warn("Optional cache write failed"); |
| 14 | } |
| 15 | return data; |
| 16 | } |
Explanation (EN)
The parser validates cached data, authoritative fetch errors propagate, and logs do not include raw keys or payloads. The adapter owns TTL validation.
Objašnjenje (HR)
Parser validira podatke iz cachea, pogreške mjerodavnog izvora propagiraju se, a logovi ne sadrže sirove ključeve ni sadržaj. Adapter validira TTL.
Notes (EN)
For an optional acceleration cache, isolate cache failures from authoritative fetch failures, validate decoded data and fall back to the real source within its capacity budget.
Exceptions / Tradeoffs (EN)
If a cache is a hard correctness dependency (e.g. distributed lock), a failure there may legitimately need to abort — but that should be a deliberate, documented choice. Balance against do-not-silently-default-on-error-for-critical-values: degrade gracefully on cache miss/corruption only by falling through to the real source, never by inventing a value. Do not fail open for authorization, revocation, locking or rate-limit state. Bound fallback load/coalesce requests during outages, and sanitize cache keys and errors before logging.
Iznimke / Tradeoffi (HR)
Cache koji je uvjet ispravnosti, poput distribuiranog zaključavanja, smije zaustaviti operaciju pri kvaru. Fallback za obični cache mora čitati pravi izvor, bez izmišljanja vrijednosti. Autorizacija, opoziv pristupa, lockovi i rate limit ne smiju prijeći u fail-open. Ograniči opterećenje izvora tijekom ispada, objedini istodobne zahtjeve te očisti ključeve i pogreške prije logiranja.