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).
Keep fallible initialization out of constructors
Move work that can throw (client construction, connection setup) into a lifecycle hook, not the constructor.
Bad example
| 1 | @Injectable() |
| 2 | export class CacheService implements OnModuleInit { |
| 3 | private readonly client: CacheClient; |
| 4 |
|
| 5 | constructor(private readonly config: CacheConfiguration) { |
| 6 | // throws synchronously on a malformed URL/port, aborting DI container construction |
| 7 | this.client = new CacheClient({ url: buildUrl(config) }); |
| 8 | } |
| 9 |
|
| 10 | async onModuleInit() { |
| 11 | await this.client.init(); |
| 12 | } |
| 13 | } |
Explanation (EN)
Constructing a client that can throw (e.g. on a malformed URL from bad config) inside the class constructor means a bad config crashes the entire dependency-injection container at bootstrap, taking down the whole app instead of just this one dependency.
Objašnjenje (HR)
Ako se u konstruktoru instancira klijent koji može baciti grešku (npr. na neispravnom URL-u zbog lošeg configa), loš config sruši cijeli DI kontejner pri pokretanju, umjesto da padne samo ta jedna ovisnost.
Good example
| 1 | @Injectable() |
| 2 | export class CacheService implements OnModuleInit { |
| 3 | private client?: CacheClient; |
| 4 |
|
| 5 | constructor(private readonly config: CacheConfiguration) {} |
| 6 |
|
| 7 | async onModuleInit() { |
| 8 | try { |
| 9 | this.client = new CacheClient({ url: buildUrl(this.config) }); |
| 10 | await this.client.init(); |
| 11 | } catch (err) { |
| 12 | this.logger.warn(`Cache init failed: ${(err as Error).message}`); |
| 13 | } |
| 14 | } |
| 15 | } |
Explanation (EN)
Move any operation that can fail into a lifecycle hook wrapped in try/catch, so a bad dependency degrades gracefully instead of preventing the whole application from starting.
Objašnjenje (HR)
Premjesti sve što može pući u lifecycle hook omotan try/catch blokom, tako da loša ovisnost samo degradira funkcionalnost umjesto da spriječi pokretanje cijele aplikacije.
Notes (EN)
This applies to any DI framework (NestJS, Angular, Spring, etc.) where constructors run during container wiring, not just at the point you expect.
Bilješke (HR)
Ovo vrijedi za svaki DI framework (NestJS, Angular, Spring itd.) gdje se konstruktori izvršavaju tijekom povezivanja kontejnera, a ne samo u trenutku kad to očekuješ.