typescript.promise_no_catch
Stability
High
Causes Production Outages
Detects Promises without .catch() handler or try/catch in async functions.
Why It Matters
Section titled “Why It Matters”Unhandled promise rejections can crash Node.js:
- Process crash — Node.js 15+ crashes on unhandled rejections
- Silent failures — Earlier versions just warn and continue
- Lost errors — Rejections vanish into the void
- Unpredictable state — Operations fail but code assumes success
Every promise must have error handling.
Example
Section titled “Example”// ❌ BeforefetchData().then(data => process(data));// If fetchData rejects, nothing catches it
async function loadUser() { const user = await getUser(id); // No try/catch return user;}// ✅ AfterfetchData() .then(data => process(data)) .catch(error => console.error('Failed to fetch:', error));
async function loadUser() { try { const user = await getUser(id); return user; } catch (error) { console.error('Failed to load user:', error); throw error; }}What Unfault Detects
Section titled “What Unfault Detects”.then()without.catch()awaitwithout surrounding try/catch- Floating promises (not awaited or returned)
Auto-Fix
Section titled “Auto-Fix”Unfault can add .catch() handlers or wrap in try/catch when the promise chain is clearly identified.
Best Practices
Section titled “Best Practices”// Always chain .catch() with .then()promise .then(handleSuccess) .catch(handleError);
// Use try/catch with async/awaitasync function doWork() { try { await step1(); await step2(); } catch (error) { handleError(error); }}
// For fire-and-forget, handle explicitlyvoid sendAnalytics(event).catch(console.error);
// Top-level asyncmain().catch(error => { console.error('Unhandled error:', error); process.exit(1);});Node.js Behavior
Section titled “Node.js Behavior”// Node.js 15+ crashes on unhandled rejections// You can customize this:process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled Rejection:', reason); // Decide: log and continue or exit});