Bare bones Promises/A+ implementation with essential extensions for readable, performant asynchronous operation handling.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Development utilities for tracking and debugging unhandled promise rejections. Helps identify potential memory leaks and uncaught errors in promise chains.
Enables unhandled rejection tracking with configurable options.
/**
* Enables unhandled rejection tracking
* @param {Object} [options] - Configuration options
* @param {boolean} [options.allRejections=false] - Track all rejections, not just reference/type errors
* @param {Array<ErrorConstructor>} [options.whitelist] - Error types to track (default: [ReferenceError, TypeError, RangeError])
* @param {function} [options.onUnhandled] - Custom handler for unhandled rejections
* @param {function} [options.onHandled] - Custom handler for subsequently handled rejections
* @returns {void}
*/
const rejectionTracking = require('promise/lib/rejection-tracking');
rejectionTracking.enable(options);Usage Examples:
const rejectionTracking = require('promise/lib/rejection-tracking');
// Basic tracking (default: only ReferenceError and TypeError)
rejectionTracking.enable();
// Track all rejections (warning: may have false positives)
rejectionTracking.enable({
allRejections: true
});
// Custom error tracking
rejectionTracking.enable({
whitelist: [TypeError, ReferenceError, RangeError]
});
// Custom handlers
rejectionTracking.enable({
onUnhandled: (id, error) => {
console.error(`Unhandled rejection #${id}:`, error);
// Log to monitoring service
logToService('unhandled-rejection', { id, error: error.stack });
},
onHandled: (id, error) => {
console.warn(`Previously unhandled rejection #${id} was handled:`, error.message);
}
});Disables unhandled rejection tracking.
/**
* Disables unhandled rejection tracking
* @returns {void}
*/
rejectionTracking.disable();Usage Examples:
const rejectionTracking = require('promise/lib/rejection-tracking');
// Enable tracking
rejectionTracking.enable();
// ... application code ...
// Disable tracking (e.g., for production)
rejectionTracking.disable();When true, tracks all promise rejections regardless of error type. Use with caution as it may produce false positives.
const rejectionTracking = require('promise/lib/rejection-tracking');
// Track everything - useful for debugging specific issues
rejectionTracking.enable({
allRejections: true
});
// Example: This will be tracked even though it might be intentional
fetch('/api/data')
.catch(error => {
// Handled, but was briefly unhandled
handleNetworkError(error);
});Array of error constructors to track. Defaults to [ReferenceError, TypeError, RangeError].
const rejectionTracking = require('promise/lib/rejection-tracking');
// Custom error types to track
rejectionTracking.enable({
whitelist: [
ReferenceError, // Default
TypeError, // Default
RangeError, // Default
SyntaxError, // Custom addition
CustomError // Custom addition
]
});
class CustomError extends Error {
constructor(message) {
super(message);
this.name = 'CustomError';
}
}Provide custom functions to handle unhandled and subsequently handled rejections.
const rejectionTracking = require('promise/lib/rejection-tracking');
rejectionTracking.enable({
onUnhandled: (id, error) => {
// Custom logging
const timestamp = new Date().toISOString();
console.error(`[${timestamp}] Unhandled Promise Rejection #${id}`);
console.error('Error:', error.stack);
// Send to monitoring service
if (process.env.NODE_ENV === 'production') {
sendToMonitoring({
type: 'unhandled-promise-rejection',
id,
error: error.message,
stack: error.stack,
timestamp
});
}
},
onHandled: (id, error) => {
console.warn(`Promise rejection #${id} was handled after being logged`);
console.warn('This indicates the error handler was attached too late');
}
});const rejectionTracking = require('promise/lib/rejection-tracking');
rejectionTracking.enable();
// This will be logged after 100ms if not handled
Promise.reject(new TypeError('Undefined variable'));
// This will be logged after 2000ms if not handled
Promise.reject(new Error('Network timeout'));
// This won't be logged (handled within delay)
Promise.reject(new Error('Will be handled'))
.catch(error => console.log('Handled:', error.message));The system can detect when a rejection is handled after being logged as unhandled.
const rejectionTracking = require('promise/lib/rejection-tracking');
rejectionTracking.enable();
const promise = Promise.reject(new Error('Late handling test'));
// After 2+ seconds, attach handler
setTimeout(() => {
promise.catch(error => {
console.log('Finally handled:', error.message);
// This will trigger onHandled callback
});
}, 3000);const rejectionTracking = require('promise/lib/rejection-tracking');
if (process.env.NODE_ENV === 'development') {
// Aggressive tracking in development
rejectionTracking.enable({
allRejections: true,
onUnhandled: (id, error) => {
console.error('🚨 Unhandled Promise Rejection:', error);
console.trace(); // Show stack trace
}
});
} else if (process.env.NODE_ENV === 'staging') {
// Conservative tracking in staging
rejectionTracking.enable({
onUnhandled: (id, error) => {
logToService('unhandled-rejection', { id, error: error.stack });
}
});
}
// Disabled in productionconst rejectionTracking = require('promise/lib/rejection-tracking');
// For testing - track all rejections
function enableTestingMode() {
const unhandledRejections = [];
rejectionTracking.enable({
allRejections: true,
onUnhandled: (id, error) => {
unhandledRejections.push({ id, error });
}
});
return {
getUnhandledRejections: () => unhandledRejections.slice(),
clearUnhandledRejections: () => unhandledRejections.splice(0),
disable: () => rejectionTracking.disable()
};
}
// Usage in tests
const tracker = enableTestingMode();
// Run test code...
const unhandled = tracker.getUnhandledRejections();
if (unhandled.length > 0) {
console.warn('Test produced unhandled rejections:', unhandled);
}
tracker.disable();const rejectionTracking = require('promise/lib/rejection-tracking');
rejectionTracking.enable({
allRejections: true,
onUnhandled: (id, error) => {
console.error(`Potential memory leak - unhandled rejection #${id}`);
console.error('Error:', error.message);
// In production, you might want to:
// - Log to monitoring service
// - Increment metrics counter
// - Alert development team
}
});const rejectionTracking = require('promise/lib/rejection-tracking');
rejectionTracking.enable({
onUnhandled: (id, error) => {
// Check if it's an API-related error
if (error.message.includes('fetch') || error.code === 'NETWORK_ERROR') {
console.error(`Unhandled API error #${id}:`, error.message);
// Track API reliability metrics
incrementMetric('api.unhandled_errors');
}
}
});/**
* Options for enabling rejection tracking
*/
interface RejectionTrackingOptions {
/** Track all rejections, not just reference/type errors */
allRejections?: boolean;
/** Error constructors to track (default: [ReferenceError, TypeError, RangeError]) */
whitelist?: ErrorConstructor[];
/** Custom handler for unhandled rejections */
onUnhandled?: (id: number, error: any) => void;
/** Custom handler for subsequently handled rejections */
onHandled?: (id: number, error: any) => void;
}Install with Tessl CLI
npx tessl i tessl/npm-promise