Sharpening the NestJS Workflow: Strict ESLint Rules for Safer Code
In the crm-saas-backend project, maintaining code quality is just as important as building new features. As our codebase grows, relying on developers to manually track side effects and decorator behavior becomes unsustainable. Recently, I focused on refining our ESLint configuration to enforce stricter standards for decorators and asynchronous operations.
The Problem: Silent Failures and Hidden Dependencies
When working with complex frameworks like NestJS, developers often use decorators for dependency injection or route handling. If these aren't configured correctly, or if we accidentally leave floating promises (unhandled async operations) in our controllers, we introduce subtle bugs that only surface under heavy load or specific edge cases.
Think of it like cooking in a busy restaurant: if you start an order (a promise) but forget to monitor it, the dish never reaches the table. In code, a floating promise means a background task that might fail without our knowledge.
Refining the ESLint Strategy
To address this, we updated our linting strategy. The goal was to make the developer experience more predictable by catching these issues at compile time rather than runtime.
Handling Promises Safely
To prevent floating promises, we enabled strict rules that ensure every asynchronous call is either await-ed, returned, or explicitly marked with void.
// Before: Potential floating promise
userService.sendWelcomeEmail(user.id);
// After: Explicitly handled or voided
void userService.sendWelcomeEmail(user.id);
// OR
await userService.sendWelcomeEmail(user.id);
Decorator Integrity
Decorators are the backbone of NestJS. We tightened our linting to ensure that decorators are consistently applied, preventing incorrect usage that could lead to runtime DI errors. By enforcing a stricter structure, we ensure that metadata is registered exactly where the framework expects it.
The Outcome: Better Predictability
By codifying these best practices, we reduce the cognitive load on the team. We no longer need to check for these patterns during code reviews—the linter does it for us. This leaves more time to focus on business logic and architecture rather than chasing down unhandled async exceptions.
Actionable Takeaway
Review your project's ESLint configuration today. If you are using TypeScript, ensure you have @typescript-eslint/no-floating-promises and strict decorator checks enabled. Even if it causes a flood of errors initially, fixing them will uncover hidden bugs you didn't know existed.
Generated with Gitvlg.com