Rules Hub
Code Ruleset
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Keep unavailable lookups distinct from successful empty or missing results
Preserve separate outcomes for successful data, legitimate absence and upstream failure so callers can show errors, retry or remove stale references according to the domain contract.
Bad example
| 1 | async function relatedIds(id: number): Promise<number[] | undefined> { |
| 2 | try { |
| 3 | return (await directory.lookup(id))?.relatedIds; |
| 4 | } catch { |
| 5 | return undefined; |
| 6 | } |
| 7 | } |
Explanation (EN)
A removed record and a failed request produce the same sentinel, preventing the caller from choosing a valid cleanup or retry.
Objašnjenje (HR)
Uklonjen zapis i neuspješan zahtjev vraćaju isti signal, pa pozivatelj ne može razlikovati valjano čišćenje od potrebe za ponovnim pokušajem.
Good example
| 1 | type Lookup = |
| 2 | | { status: 'found'; ids: number[] } |
| 3 | | { status: 'missing' } |
| 4 | | { status: 'unavailable'; error: unknown }; |
| 5 |
|
| 6 | async function relatedIds(id: number): Promise<Lookup> { |
| 7 | try { |
| 8 | const record = await directory.lookup(id); |
| 9 | return record |
| 10 | ? { status: 'found', ids: record.relatedIds } |
| 11 | : { status: 'missing' }; |
| 12 | } catch (error) { |
| 13 | return { status: 'unavailable', error }; |
| 14 | } |
| 15 | } |
Explanation (EN)
The caller can distinguish successful emptiness, a removed record and a dependency failure without inferring them from one ambiguous sentinel.
Objašnjenje (HR)
Pozivatelj razlikuje uspješan prazan rezultat, uklonjen zapis i kvar ovisnog servisa bez zaključivanja iz jednog dvosmislenog signala.
Notes (EN)
Apply at API, repository and loader boundaries that can legitimately return no records. Preserve failures through wrappers rather than returning an empty array or null that callers treat as success. A missing parent must not automatically become a permanent server error when removing a stale user-owned association. Explicitly define whether missing means no related records, not found, or reconciliation required, and test absence separately from outage.
Bilješke (HR)
Primijeni na granicama API-ja, repozitorija i loadera koji valjano mogu vratiti bez zapisa. Očuvaj grešku kroz omotače umjesto praznog polja ili null vrijednosti koju pozivatelji tumače kao uspjeh. Nedostajući roditelj ne smije automatski značiti trajnu poslužiteljsku grešku pri uklanjanju zastarjele korisničke veze. Izričito odredi znači li odsutnost da nema povezanih zapisa, da zapis nije pronađen ili da je potrebno usklađivanje. Odvojeno testiraj odsutnost i nedostupnost.
Exceptions / Tradeoffs (EN)
Throwing typed errors with a documented missing sentinel is also valid. Best-effort consumers may intentionally omit unavailable enrichment, but must not silently claim authoritative emptiness or completed cleanup. Do not treat missing data as proof that unknown associations are safe to delete.
Iznimke / Tradeoffi (HR)
Valjano je i bacanje tipizirane greške uz dokumentiran signal nedostajućeg zapisa. Potrošači smiju namjerno izostaviti nedostupnu dopunu, ali ne smiju tiho tvrditi da je rezultat mjerodavno prazan ili da je čišćenje dovršeno. Odsutnost podatka nije dokaz da je nepoznate veze sigurno obrisati.