Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Do not silently return a default value when a critical fetch fails
Don't swallow errors and return a neutral default for values that feed downstream calculations; propagate or make the fallback an explicit decision.
Bad example
| 1 | async fetchExchangeRate(currency: Currency, date: string): Promise<number> { |
| 2 | return lastValueFrom( |
| 3 | this.http.get<{ rate: number }>(`${this.baseUrl}/exchange-rate`, { params: { currency, date } }), |
| 4 | ) |
| 5 | .then((res) => res.data.rate) |
| 6 | .catch((error) => { |
| 7 | this.logger.error(`Failed to fetch rate: ${error.message}`); |
| 8 | // Silently returns 1 — downstream money math is now silently wrong |
| 9 | return 1; |
| 10 | }); |
| 11 | } |
Explanation (EN)
Returning 1 on any failure means a network blip produces a transaction recorded at the wrong value, with no error surfaced to the user or caller.
Objašnjenje (HR)
Vracanje 1 pri bilo kakvom kvaru znaci da mrezni problem rezultira transakcijom zabiljezenom s pogresnom vrijednoscu, bez ikakve greske prikazane korisniku ili pozivatelju.
Good example
| 1 | async fetchExchangeRate(currency: Currency, date: string): Promise<number> { |
| 2 | if (currency === Currency.BASE) return 1; // explicit, correct default |
| 3 | try { |
| 4 | const res = await lastValueFrom( |
| 5 | this.http.get<{ rate: number }>(`${this.baseUrl}/exchange-rate`, { params: { currency, date } }), |
| 6 | ); |
| 7 | return res.data.rate; |
| 8 | } catch (error) { |
| 9 | this.logger.error(`Failed to fetch rate for ${currency} on ${date}: ${error.message}`); |
| 10 | // Let the caller decide how to handle a missing rate (reject the request, retry, etc.) |
| 11 | throw new ServiceUnavailableException('Exchange rate unavailable'); |
| 12 | } |
| 13 | } |
Explanation (EN)
The known correct default (base currency -> 1) stays explicit, while genuine failures propagate so the caller can reject the operation instead of persisting corrupt data.
Objašnjenje (HR)
Poznati ispravan default (bazna valuta -> 1) ostaje eksplicitan, dok se stvarne greske propagiraju kako bi pozivatelj mogao odbiti operaciju umjesto da spremi neispravne podatke.
Exceptions / Tradeoffs (EN)
A silent default is acceptable when the fallback is genuinely correct for the domain and the value is non-critical (e.g., a cached display hint), but document why. Balance against wrap-external-calls-error-handling: when the value feeds a downstream calculation, fail loudly rather than return a neutral default that corrupts results. Balance against cache-layer-must-degrade-gracefully: if the cached value is a critical calculation input, recompute or fail; do not substitute a default.
Iznimke / Tradeoffi (HR)
Tihi default je prihvatljiv kada je zamjenska vrijednost stvarno ispravna za domenu i vrijednost nije kriticna (npr. predmemorirani prikaz), ali dokumentiraj zasto.