refactor(serverUtils.js): better error handling

This commit is contained in:
Rim 2025-04-17 06:43:54 -04:00
parent 3774a4265c
commit 6a5cde6f40

View File

@ -154,10 +154,13 @@ const activeSessions = new Map();
// Utility function to create a timeout promise // Utility function to create a timeout promise
const timeoutPromise = (ms) => { const timeoutPromise = (ms) => {
return new Promise((_, reject) => { return new Promise((_, reject) => {
setTimeout(() => reject(new ApiTimeoutError(`Request timed out after ${ms}ms`)), ms); setTimeout(
}); () => reject(new ApiTimeoutError(`Request timed out after ${ms}ms`)),
}; ms
);
});
};
// Helper function to ensure login // Helper function to ensure login
const ensureLogin = async (ssoToken) => { const ensureLogin = async (ssoToken) => {
@ -179,80 +182,81 @@ const ensureLogin = async (ssoToken) => {
} }
}; };
// Helper function to handle API errors // Create custom error classes
class ApiTimeoutError extends Error { class ApiTimeoutError extends Error {
constructor(message = 'API request timed out') { constructor(message = 'API request timed out') {
super(message); super(message);
this.name = 'ApiTimeoutError'; this.name = 'ApiTimeoutError';
}
} }
}
class ApiAuthError extends Error {
constructor(message = 'Authentication failed') { class ApiAuthError extends Error {
super(message); constructor(message = 'Authentication failed') {
this.name = 'ApiAuthError'; super(message);
} this.name = 'ApiAuthError';
} }
}
class ApiDataError extends Error {
constructor(message = 'Data processing error') { class ApiDataError extends Error {
super(message); constructor(message = 'Data processing error') {
this.name = 'ApiDataError'; super(message);
} this.name = 'ApiDataError';
} }
}
// Helper function to handle API errors
const handleApiError = (error, res) => { // Helper function to handle API errors
logger.error('API Error:', error); const handleApiError = (error, res) => {
logger.error(`Error Stack: ${error.stack}`); logger.error('API Error:', error);
logger.error(`Error Time: ${global.Utils.toIsoString(new Date())}`); logger.error(`Error Stack: ${error.stack}`);
logger.error(`Error Time: ${global.Utils.toIsoString(new Date())}`);
// Map error types to appropriate responses
const errorResponses = { // Map error types to appropriate responses
'ApiTimeoutError': { const errorResponses = {
status: 200, ApiTimeoutError: {
body: { status: 200,
status: 'error', body: {
message: 'The request timed out. Please try again.', status: 'error',
error_type: 'timeout', message: 'The request timed out. Please try again.',
timestamp: global.Utils.toIsoString(new Date()) error_type: 'timeout',
} timestamp: global.Utils.toIsoString(new Date()),
}, },
'ApiAuthError': { },
status: 200, ApiAuthError: {
body: { status: 200,
status: 'error', body: {
message: 'Authentication failed. Please check your SSO token.', status: 'error',
error_type: 'auth_failure', message: 'Authentication failed. Please check your SSO token.',
timestamp: global.Utils.toIsoString(new Date()) error_type: 'auth_failure',
} timestamp: global.Utils.toIsoString(new Date()),
}, },
'SyntaxError': { },
status: 200, SyntaxError: {
body: { status: 200,
status: 'error', body: {
message: 'Failed to parse API response. This usually means the SSO token is invalid or expired.', status: 'error',
error_type: 'InvalidResponseError', message:
timestamp: global.Utils.toIsoString(new Date()) 'Failed to parse API response. This usually means the SSO token is invalid or expired.',
} error_type: 'InvalidResponseError',
timestamp: global.Utils.toIsoString(new Date()),
}, },
'default': { },
status: 200, default: {
body: { status: 200,
status: 'error', body: {
message: error.message || 'An unknown error occurred', status: 'error',
error_type: error.name || 'UnknownError', message: error.message || 'An unknown error occurred',
timestamp: global.Utils.toIsoString(new Date()) error_type: error.name || 'UnknownError',
} timestamp: global.Utils.toIsoString(new Date()),
} },
}; },
// Get the appropriate response or use default
const response = errorResponses[error.name] || errorResponses.default;
return res.status(response.status).json(response.body);
}; };
// Get the appropriate response or use default
const response = errorResponses[error.name] || errorResponses.default;
return res.status(response.status).json(response.body);
};
// Helper function to remove sensitive data from headers // Helper function to remove sensitive data from headers
function sanitizeHeaders(headers) { function sanitizeHeaders(headers) {
const safeHeaders = { ...headers }; const safeHeaders = { ...headers };