File size: 3,300 Bytes
5d64417 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
/**
* Task 8.1: Standardized Error Logging Utility
* Provides consistent error logging across all components
*/
export class ErrorLogger {
constructor(componentName) {
this.componentName = componentName;
}
/**
* Log an error with standardized format
* @param {string} message - Error message
* @param {Object} details - Additional error details
* @param {Error} error - Original error object (optional)
*/
log(message, details = {}, error = null) {
const logEntry = {
timestamp: new Date().toISOString(),
component: this.componentName,
level: 'error',
message: message,
details: details,
stack: error?.stack || new Error().stack
};
// Log to console with formatting
console.error(`[${logEntry.timestamp}] [${logEntry.component}] ERROR:`, message);
if (Object.keys(details).length > 0) {
console.error('Details:', details);
}
if (error) {
console.error('Original error:', error.message);
console.error('Stack trace:', error.stack);
}
return logEntry;
}
/**
* Log a validation error with expected vs actual schema
* @param {string} field - Field that failed validation
* @param {*} expected - Expected value/type
* @param {*} actual - Actual value/type
*/
logValidationError(field, expected, actual) {
return this.log('Validation Error', {
field: field,
expected: expected,
actual: actual,
type: 'validation'
});
}
/**
* Log a warning (non-fatal issue)
* @param {string} message - Warning message
* @param {Object} details - Additional details
*/
warn(message, details = {}) {
const logEntry = {
timestamp: new Date().toISOString(),
component: this.componentName,
level: 'warning',
message: message,
details: details
};
console.warn(`[${logEntry.timestamp}] [${logEntry.component}] WARNING:`, message);
if (Object.keys(details).length > 0) {
console.warn('Details:', details);
}
return logEntry;
}
/**
* Log an info message
* @param {string} message - Info message
* @param {Object} details - Additional details
*/
info(message, details = {}) {
const logEntry = {
timestamp: new Date().toISOString(),
component: this.componentName,
level: 'info',
message: message,
details: details
};
console.log(`[${logEntry.timestamp}] [${logEntry.component}] INFO:`, message);
if (Object.keys(details).length > 0) {
console.log('Details:', details);
}
return logEntry;
}
}
/**
* Create a logger instance for a component
* @param {string} componentName - Name of the component
* @returns {ErrorLogger} Logger instance
*/
export function createLogger(componentName) {
return new ErrorLogger(componentName);
}
/**
* Format validation errors with expected vs actual schema
* @param {Array} errors - Array of validation errors
* @returns {string} Formatted error message
*/
export function formatValidationErrors(errors) {
if (!errors || errors.length === 0) {
return 'No validation errors';
}
return errors.map((err, index) => {
return `${index + 1}. ${err.field}: Expected ${err.expected}, got ${err.actual}`;
}).join('\n');
}
|