reorg
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
const { logError } = require('./logger');
|
||||
|
||||
/**
|
||||
* Wraps an async function to ensure errors are caught and logged
|
||||
* @param {Function} fn - Async function to wrap
|
||||
* @param {string} context - Context name for logging
|
||||
* @returns {Function} - Wrapped function
|
||||
*/
|
||||
function wrapAsync(fn, context = 'Unknown') {
|
||||
return async (...args) => {
|
||||
try {
|
||||
return await fn(...args);
|
||||
} catch (err) {
|
||||
logError('AsyncError', `Unhandled error in ${context}: ${err.message}`);
|
||||
logError('AsyncError', err.stack);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an async callback to ensure errors are caught
|
||||
* @param {Function} fn - Async callback function
|
||||
* @param {string} context - Context name for logging
|
||||
* @returns {Function} - Wrapped callback
|
||||
*/
|
||||
function wrapAsyncCallback(fn, context = 'Unknown') {
|
||||
return async (...args) => {
|
||||
try {
|
||||
return await fn(...args);
|
||||
} catch (err) {
|
||||
logError('AsyncError', `Unhandled error in callback ${context}: ${err.message}`);
|
||||
logError('AsyncError', err.stack);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a promise that never rejects (catches all errors)
|
||||
* @param {Promise} promise - Promise to wrap
|
||||
* @param {string} context - Context for error logging
|
||||
* @returns {Promise} - Promise that resolves with { success, result, error }
|
||||
*/
|
||||
async function safePromise(promise, context = 'Unknown') {
|
||||
try {
|
||||
const result = await promise;
|
||||
return { success: true, result };
|
||||
} catch (err) {
|
||||
logError('AsyncError', `Error in safe promise ${context}: ${err.message}`);
|
||||
return { success: false, error: err };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes multiple promises safely, collecting results and errors
|
||||
* @param {Array<Promise>} promises - Array of promises
|
||||
* @param {string} context - Context for error logging
|
||||
* @returns {Promise<Array>} - Array of { success, result, error } objects
|
||||
*/
|
||||
async function safeAll(promises, context = 'Unknown') {
|
||||
const results = await Promise.allSettled(promises);
|
||||
return results.map((result, index) => {
|
||||
if (result.status === 'fulfilled') {
|
||||
return { success: true, result: result.value };
|
||||
} else {
|
||||
logError('AsyncError', `Error in safeAll promise ${index} (${context}): ${result.reason?.message || result.reason}`);
|
||||
return { success: false, error: result.reason };
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retries an async function with exponential backoff
|
||||
* @param {Function} fn - Async function to retry
|
||||
* @param {object} options - Retry options
|
||||
* @param {number} options.maxRetries - Maximum number of retries
|
||||
* @param {number} options.initialDelay - Initial delay in ms
|
||||
* @param {number} options.maxDelay - Maximum delay in ms
|
||||
* @param {Function} options.shouldRetry - Function to determine if error should be retried
|
||||
* @returns {Promise} - Result of function call
|
||||
*/
|
||||
async function retryWithBackoff(fn, options = {}) {
|
||||
const {
|
||||
maxRetries = 3,
|
||||
initialDelay = 1000,
|
||||
maxDelay = 10000,
|
||||
shouldRetry = () => true
|
||||
} = options;
|
||||
|
||||
let lastError;
|
||||
let delay = initialDelay;
|
||||
|
||||
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
||||
try {
|
||||
return await fn();
|
||||
} catch (err) {
|
||||
lastError = err;
|
||||
|
||||
if (attempt === maxRetries || !shouldRetry(err)) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
logError('Retry', `Attempt ${attempt + 1}/${maxRetries + 1} failed: ${err.message}. Retrying in ${delay}ms...`);
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
delay = Math.min(delay * 2, maxDelay);
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
wrapAsync,
|
||||
wrapAsyncCallback,
|
||||
safePromise,
|
||||
safeAll,
|
||||
retryWithBackoff
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user