qapinterface
Version:
Comprehensive API utilities for Node.js applications including authentication, security, request processing, and response handling with zero external dependencies
135 lines (124 loc) • 4.2 kB
JavaScript
/**
* Enhanced Controller Error Handler with qerrors Integration
*
* Provides comprehensive error handling for Express controllers with
* automatic error classification, structured logging, and AI analysis.
*/
// Direct imports to avoid circular dependency
let qerrorsHandler, logError;
try {
const qerrorsModule = require('qerrors/lib/errorTypes');
qerrorsHandler = qerrorsModule.handleControllerError;
logError = qerrorsModule.logError;
} catch (error) {
// Fallback handlers if qerrors not available
qerrorsHandler = null;
logError = null;
}
const { createEnhancedError, getSeverityForType, ErrorTypes } = require('./enhanced-error-factory');
/**
* Enhanced controller error handler with AI analysis
* @param {Error|object} error - Error object or message
* @param {object} req - Express request object
* @param {object} res - Express response object
* @param {string} context - Function or route context
* @param {object} metadata - Additional context metadata
*/
async function handleControllerErrorEnhanced(error, req, res, context = 'unknown_controller', metadata = {}) {
// Convert string errors to proper error objects
const errorObj = typeof error === 'string' ?
createEnhancedError(error, ErrorTypes.SYSTEM, context, metadata) :
error;
// Add request context to error
const requestContext = {
requestId: req.id || req.headers['x-request-id'],
method: req.method,
url: req.originalUrl || req.url,
userAgent: req.get('User-Agent'),
ip: req.ip || req.connection.remoteAddress,
timestamp: new Date().toISOString(),
...metadata
};
// Enhanced error object with full context
const enhancedError = {
...errorObj,
context: context,
requestContext,
severity: errorObj.severity || getSeverityForType(errorObj.type || ErrorTypes.SYSTEM)
};
// Log error with enhanced context
if (logError) {
try {
await logError('Controller Error', enhancedError, context);
} catch (logErr) {
console.error('Error logging failed:', logErr.message);
}
}
// Use qerrors handler for response (with fallback)
try {
if (qerrorsHandler) {
await qerrorsHandler(res, enhancedError, context, requestContext);
} else {
// Fallback to basic response
res.status(enhancedError.statusCode || 500).json({
success: false,
error: {
message: enhancedError.message || 'Internal Server Error',
statusCode: enhancedError.statusCode || 500,
type: enhancedError.type || ErrorTypes.SYSTEM
},
timestamp: new Date().toISOString()
});
}
} catch (handlerErr) {
console.error('Error handler failed:', handlerErr.message);
// Ultimate fallback
if (!res.headersSent) {
res.status(500).json({
success: false,
error: { message: 'Internal Server Error', statusCode: 500 },
timestamp: new Date().toISOString()
});
}
}
}
/**
* Middleware wrapper for enhanced error handling
* @param {Function} controllerFunction - Controller function to wrap
* @param {string} context - Context name for error tracking
* @returns {Function} Enhanced controller middleware
*/
function withErrorHandling(controllerFunction, context) {
return async (req, res, next) => {
try {
await controllerFunction(req, res, next);
} catch (error) {
await handleControllerErrorEnhanced(error, req, res, context, {
functionName: controllerFunction.name || 'anonymous'
});
}
};
}
/**
* Express error middleware with enhanced handling
* @param {Error} err - Error object
* @param {object} req - Express request
* @param {object} res - Express response
* @param {Function} next - Express next function
*/
async function enhancedErrorMiddleware(err, req, res, next) {
// Skip if headers already sent
if (res.headersSent) {
return next(err);
}
// Handle the error with full enhancement
await handleControllerErrorEnhanced(err, req, res, 'error_middleware', {
middlewareError: true,
stack: err.stack
});
}
module.exports = {
handleControllerErrorEnhanced,
withErrorHandling,
enhancedErrorMiddleware
};