0
# Rejection Tracking
1
2
Development utilities for tracking and debugging unhandled promise rejections. Helps identify potential memory leaks and uncaught errors in promise chains.
3
4
## Capabilities
5
6
### enable
7
8
Enables unhandled rejection tracking with configurable options.
9
10
```javascript { .api }
11
/**
12
* Enables unhandled rejection tracking
13
* @param {Object} [options] - Configuration options
14
* @param {boolean} [options.allRejections=false] - Track all rejections, not just reference/type errors
15
* @param {Array<ErrorConstructor>} [options.whitelist] - Error types to track (default: [ReferenceError, TypeError, RangeError])
16
* @param {function} [options.onUnhandled] - Custom handler for unhandled rejections
17
* @param {function} [options.onHandled] - Custom handler for subsequently handled rejections
18
* @returns {void}
19
*/
20
const rejectionTracking = require('promise/lib/rejection-tracking');
21
rejectionTracking.enable(options);
22
```
23
24
**Usage Examples:**
25
26
```javascript
27
const rejectionTracking = require('promise/lib/rejection-tracking');
28
29
// Basic tracking (default: only ReferenceError and TypeError)
30
rejectionTracking.enable();
31
32
// Track all rejections (warning: may have false positives)
33
rejectionTracking.enable({
34
allRejections: true
35
});
36
37
// Custom error tracking
38
rejectionTracking.enable({
39
whitelist: [TypeError, ReferenceError, RangeError]
40
});
41
42
// Custom handlers
43
rejectionTracking.enable({
44
onUnhandled: (id, error) => {
45
console.error(`Unhandled rejection #${id}:`, error);
46
// Log to monitoring service
47
logToService('unhandled-rejection', { id, error: error.stack });
48
},
49
onHandled: (id, error) => {
50
console.warn(`Previously unhandled rejection #${id} was handled:`, error.message);
51
}
52
});
53
```
54
55
### disable
56
57
Disables unhandled rejection tracking.
58
59
```javascript { .api }
60
/**
61
* Disables unhandled rejection tracking
62
* @returns {void}
63
*/
64
rejectionTracking.disable();
65
```
66
67
**Usage Examples:**
68
69
```javascript
70
const rejectionTracking = require('promise/lib/rejection-tracking');
71
72
// Enable tracking
73
rejectionTracking.enable();
74
75
// ... application code ...
76
77
// Disable tracking (e.g., for production)
78
rejectionTracking.disable();
79
```
80
81
## Configuration Options
82
83
### allRejections
84
85
When `true`, tracks all promise rejections regardless of error type. Use with caution as it may produce false positives.
86
87
```javascript
88
const rejectionTracking = require('promise/lib/rejection-tracking');
89
90
// Track everything - useful for debugging specific issues
91
rejectionTracking.enable({
92
allRejections: true
93
});
94
95
// Example: This will be tracked even though it might be intentional
96
fetch('/api/data')
97
.catch(error => {
98
// Handled, but was briefly unhandled
99
handleNetworkError(error);
100
});
101
```
102
103
### whitelist
104
105
Array of error constructors to track. Defaults to `[ReferenceError, TypeError, RangeError]`.
106
107
```javascript
108
const rejectionTracking = require('promise/lib/rejection-tracking');
109
110
// Custom error types to track
111
rejectionTracking.enable({
112
whitelist: [
113
ReferenceError, // Default
114
TypeError, // Default
115
RangeError, // Default
116
SyntaxError, // Custom addition
117
CustomError // Custom addition
118
]
119
});
120
121
class CustomError extends Error {
122
constructor(message) {
123
super(message);
124
this.name = 'CustomError';
125
}
126
}
127
```
128
129
### Custom Handlers
130
131
Provide custom functions to handle unhandled and subsequently handled rejections.
132
133
```javascript
134
const rejectionTracking = require('promise/lib/rejection-tracking');
135
136
rejectionTracking.enable({
137
onUnhandled: (id, error) => {
138
// Custom logging
139
const timestamp = new Date().toISOString();
140
console.error(`[${timestamp}] Unhandled Promise Rejection #${id}`);
141
console.error('Error:', error.stack);
142
143
// Send to monitoring service
144
if (process.env.NODE_ENV === 'production') {
145
sendToMonitoring({
146
type: 'unhandled-promise-rejection',
147
id,
148
error: error.message,
149
stack: error.stack,
150
timestamp
151
});
152
}
153
},
154
155
onHandled: (id, error) => {
156
console.warn(`Promise rejection #${id} was handled after being logged`);
157
console.warn('This indicates the error handler was attached too late');
158
}
159
});
160
```
161
162
## Timing and Behavior
163
164
### Detection Delays
165
166
- **ReferenceError/TypeError**: 100ms delay (likely programmer errors)
167
- **Other errors**: 2000ms delay (might be handled later)
168
169
```javascript
170
const rejectionTracking = require('promise/lib/rejection-tracking');
171
172
rejectionTracking.enable();
173
174
// This will be logged after 100ms if not handled
175
Promise.reject(new TypeError('Undefined variable'));
176
177
// This will be logged after 2000ms if not handled
178
Promise.reject(new Error('Network timeout'));
179
180
// This won't be logged (handled within delay)
181
Promise.reject(new Error('Will be handled'))
182
.catch(error => console.log('Handled:', error.message));
183
```
184
185
### Late Handling Detection
186
187
The system can detect when a rejection is handled after being logged as unhandled.
188
189
```javascript
190
const rejectionTracking = require('promise/lib/rejection-tracking');
191
192
rejectionTracking.enable();
193
194
const promise = Promise.reject(new Error('Late handling test'));
195
196
// After 2+ seconds, attach handler
197
setTimeout(() => {
198
promise.catch(error => {
199
console.log('Finally handled:', error.message);
200
// This will trigger onHandled callback
201
});
202
}, 3000);
203
```
204
205
## Development Patterns
206
207
### Development vs Production
208
209
```javascript
210
const rejectionTracking = require('promise/lib/rejection-tracking');
211
212
if (process.env.NODE_ENV === 'development') {
213
// Aggressive tracking in development
214
rejectionTracking.enable({
215
allRejections: true,
216
onUnhandled: (id, error) => {
217
console.error('🚨 Unhandled Promise Rejection:', error);
218
console.trace(); // Show stack trace
219
}
220
});
221
} else if (process.env.NODE_ENV === 'staging') {
222
// Conservative tracking in staging
223
rejectionTracking.enable({
224
onUnhandled: (id, error) => {
225
logToService('unhandled-rejection', { id, error: error.stack });
226
}
227
});
228
}
229
// Disabled in production
230
```
231
232
### Testing Integration
233
234
```javascript
235
const rejectionTracking = require('promise/lib/rejection-tracking');
236
237
// For testing - track all rejections
238
function enableTestingMode() {
239
const unhandledRejections = [];
240
241
rejectionTracking.enable({
242
allRejections: true,
243
onUnhandled: (id, error) => {
244
unhandledRejections.push({ id, error });
245
}
246
});
247
248
return {
249
getUnhandledRejections: () => unhandledRejections.slice(),
250
clearUnhandledRejections: () => unhandledRejections.splice(0),
251
disable: () => rejectionTracking.disable()
252
};
253
}
254
255
// Usage in tests
256
const tracker = enableTestingMode();
257
258
// Run test code...
259
260
const unhandled = tracker.getUnhandledRejections();
261
if (unhandled.length > 0) {
262
console.warn('Test produced unhandled rejections:', unhandled);
263
}
264
265
tracker.disable();
266
```
267
268
## Common Use Cases
269
270
### Memory Leak Detection
271
272
```javascript
273
const rejectionTracking = require('promise/lib/rejection-tracking');
274
275
rejectionTracking.enable({
276
allRejections: true,
277
onUnhandled: (id, error) => {
278
console.error(`Potential memory leak - unhandled rejection #${id}`);
279
console.error('Error:', error.message);
280
281
// In production, you might want to:
282
// - Log to monitoring service
283
// - Increment metrics counter
284
// - Alert development team
285
}
286
});
287
```
288
289
### API Error Monitoring
290
291
```javascript
292
const rejectionTracking = require('promise/lib/rejection-tracking');
293
294
rejectionTracking.enable({
295
onUnhandled: (id, error) => {
296
// Check if it's an API-related error
297
if (error.message.includes('fetch') || error.code === 'NETWORK_ERROR') {
298
console.error(`Unhandled API error #${id}:`, error.message);
299
300
// Track API reliability metrics
301
incrementMetric('api.unhandled_errors');
302
}
303
}
304
});
305
```
306
307
## Types
308
309
```javascript { .api }
310
/**
311
* Options for enabling rejection tracking
312
*/
313
interface RejectionTrackingOptions {
314
/** Track all rejections, not just reference/type errors */
315
allRejections?: boolean;
316
317
/** Error constructors to track (default: [ReferenceError, TypeError, RangeError]) */
318
whitelist?: ErrorConstructor[];
319
320
/** Custom handler for unhandled rejections */
321
onUnhandled?: (id: number, error: any) => void;
322
323
/** Custom handler for subsequently handled rejections */
324
onHandled?: (id: number, error: any) => void;
325
}
326
```