/**
* Error Handler
*
* Centralized error handling with consistent error formatting.
* Provides structured error responses across the application.
*/
/**
* Error Handler Class
*/
export class ErrorHandler {
/**
* Create an error with code and details
* @param {string} code - Error code
* @param {string} message - Error message
* @param {Object} data - Additional error data
* @returns {Error} Error object with code property
*/
createError(code, message, data = {}) {
const error = new Error(message);
error.code = code;
error.data = data;
return error;
}
/**
* Create validation error
* @param {string} message - Error message
* @param {Array} details - Validation details
* @returns {Error} Validation error
*/
createValidationError(message, details = []) {
return this.createError('VALIDATION_ERROR', message, { details });
}
/**
* Create authentication error
* @param {string} message - Error message
* @param {string} reason - Authentication failure reason
* @returns {Error} Authentication error
*/
createAuthenticationError(message, reason = null) {
return this.createError('AUTHENTICATION_FAILED', message, { reason });
}
/**
* Create permission error
* @param {string} message - Error message
* @param {string} reason - Permission denied reason
* @returns {Error} Permission error
*/
createPermissionError(message, reason = null) {
return this.createError('PERMISSION_DENIED', message, { reason });
}
/**
* Create security error
* @param {string} message - Error message
* @param {Array} issues - Security issues
* @returns {Error} Security error
*/
createSecurityError(message, issues = []) {
return this.createError('SECURITY_VIOLATION', message, { issues });
}
/**
* Create policy error
* @param {string} message - Error message
* @param {Object} violation - Policy violation details
* @returns {Error} Policy error
*/
createPolicyError(message, violation = null) {
return this.createError('POLICY_VIOLATION', message, { violation });
}
/**
* Create rate limit error
* @param {string} message - Error message
* @param {number} retryAfter - Seconds until retry
* @returns {Error} Rate limit error
*/
createRateLimitError(message, retryAfter = null) {
return this.createError('RATE_LIMIT_EXCEEDED', message, { retryAfter });
}
/**
* Create not found error
* @param {string} message - Error message
* @param {string} resource - Resource that was not found
* @returns {Error} Not found error
*/
createNotFoundError(message, resource = null) {
return this.createError('NOT_FOUND', message, { resource });
}
/**
* Create conflict error
* @param {string} message - Error message
* @param {string} reason - Conflict reason
* @returns {Error} Conflict error
*/
createConflictError(message, reason = null) {
return this.createError('CONFLICT', message, { reason });
}
/**
* Create internal error
* @param {string} message - Error message
* @param {Error} originalError - Original error
* @returns {Error} Internal error
*/
createInternalError(message, originalError = null) {
const error = this.createError('INTERNAL_ERROR', message);
if (originalError) {
error.originalError = {
message: originalError.message,
stack: originalError.stack
};
}
return error;
}
/**
* Handle an error and return formatted response
* @param {Error} error - Error to handle
* @param {string} correlationId - Correlation ID
* @returns {Object} Formatted error response
*/
handleError(error, correlationId) {
// If error already has a code, use it
if (error.code) {
return {
error: {
code: error.code,
message: error.message,
data: error.data || {},
correlationId
}
};
}
// Otherwise, create internal error
return {
error: {
code: 'INTERNAL_ERROR',
message: 'An unexpected error occurred',
data: {
correlationId,
originalMessage: error.message
}
}
};
}
/**
* Check if error is a specific type
* @param {Error} error - Error to check
* @param {string} code - Error code to check against
* @returns {boolean}
*/
isErrorType(error, code) {
return error && error.code === code;
}
/**
* Check if error is retryable
* @param {Error} error - Error to check
* @returns {boolean}
*/
isRetryable(error) {
const retryableCodes = [
'INTERNAL_ERROR',
'RATE_LIMIT_EXCEEDED',
'NETWORK_ERROR'
];
return error && retryableCodes.includes(error.code);
}
}
// Export singleton instance
export const errorHandler = new ErrorHandler();