@oxyhq/services
Version:
Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀
171 lines (158 loc) • 5.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ErrorCodes = void 0;
exports.createApiError = createApiError;
exports.getErrorCodeFromStatus = getErrorCodeFromStatus;
exports.handleHttpError = handleHttpError;
exports.logError = logError;
Object.defineProperty(exports, "retryWithBackoff", {
enumerable: true,
get: function () {
return _asyncUtils.retryAsync;
}
});
exports.validateRequiredFields = validateRequiredFields;
var _loggerUtils = require("./loggerUtils");
var _asyncUtils = require("./asyncUtils");
/**
* Error handling utilities for consistent error processing
*/
/**
* Common error codes
*/
const ErrorCodes = exports.ErrorCodes = {
// Authentication errors
UNAUTHORIZED: 'UNAUTHORIZED',
FORBIDDEN: 'FORBIDDEN',
INVALID_TOKEN: 'INVALID_TOKEN',
MISSING_TOKEN: 'MISSING_TOKEN',
// Validation errors
VALIDATION_ERROR: 'VALIDATION_ERROR',
BAD_REQUEST: 'BAD_REQUEST',
MISSING_PARAMETER: 'MISSING_PARAMETER',
INVALID_FORMAT: 'INVALID_FORMAT',
// Resource errors
NOT_FOUND: 'NOT_FOUND',
ALREADY_EXISTS: 'ALREADY_EXISTS',
CONFLICT: 'CONFLICT',
// Server errors
INTERNAL_ERROR: 'INTERNAL_ERROR',
SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',
TIMEOUT: 'TIMEOUT',
// Network errors
NETWORK_ERROR: 'NETWORK_ERROR',
CONNECTION_FAILED: 'CONNECTION_FAILED'
};
/**
* Create a standardized API error
*/
function createApiError(message, code = ErrorCodes.INTERNAL_ERROR, status = 500, details) {
return {
message,
code,
status,
details
};
}
/**
* Handle common HTTP errors and convert to ApiError
*/
function handleHttpError(error) {
// If it's already an ApiError, return it
if (error && typeof error === 'object' && 'code' in error && 'status' in error) {
return error;
}
// Handle AbortError (timeout or cancelled requests)
if (error instanceof Error && error.name === 'AbortError') {
return createApiError('Request timeout or cancelled', ErrorCodes.TIMEOUT, 0);
}
// Handle TypeError (network failures, CORS, etc.)
if (error instanceof TypeError) {
// Check if it's a network-related TypeError
if (error.message.includes('fetch') || error.message.includes('network') || error.message.includes('Failed to fetch')) {
return createApiError('Network error - failed to connect to server', ErrorCodes.NETWORK_ERROR, 0);
}
return createApiError(error.message || 'Network error occurred', ErrorCodes.NETWORK_ERROR, 0);
}
// Handle fetch Response errors - check if it has response property with status
if (error && typeof error === 'object' && 'response' in error) {
const fetchError = error;
const status = fetchError.response?.status || fetchError.status;
if (status) {
return createApiError(fetchError.message || `HTTP ${status} error`, getErrorCodeFromStatus(status), status);
}
}
// Handle standard errors
if (error instanceof Error) {
// Check for common error patterns
if (error.message.includes('timeout') || error.message.includes('aborted')) {
return createApiError('Request timeout', ErrorCodes.TIMEOUT, 0);
}
if (error.message.includes('network') || error.message.includes('fetch')) {
return createApiError(error.message || 'Network error occurred', ErrorCodes.NETWORK_ERROR, 0);
}
return createApiError(error.message || 'Unknown error occurred', ErrorCodes.INTERNAL_ERROR, 500);
}
// Handle other errors
return createApiError(String(error) || 'Unknown error occurred', ErrorCodes.INTERNAL_ERROR, 500);
}
/**
* Get error code from HTTP status
* Exported for use in other modules
*/
function getErrorCodeFromStatus(status) {
switch (status) {
case 400:
return ErrorCodes.BAD_REQUEST;
case 401:
return ErrorCodes.UNAUTHORIZED;
case 403:
return ErrorCodes.FORBIDDEN;
case 404:
return ErrorCodes.NOT_FOUND;
case 409:
return ErrorCodes.CONFLICT;
case 422:
return ErrorCodes.VALIDATION_ERROR;
case 500:
return ErrorCodes.INTERNAL_ERROR;
case 503:
return ErrorCodes.SERVICE_UNAVAILABLE;
default:
return ErrorCodes.INTERNAL_ERROR;
}
}
/**
* Validate required fields and throw error if missing
*/
function validateRequiredFields(data, fields) {
const missing = fields.filter(field => !data[field]);
if (missing.length > 0) {
throw createApiError(`Missing required fields: ${missing.join(', ')}`, ErrorCodes.MISSING_PARAMETER, 400);
}
}
/**
* Safe error logging with context
*/
function logError(error, context) {
if (error instanceof Error) {
_loggerUtils.logger.error(error.message, {
component: context || 'errorUtils',
method: 'logError',
stack: error.stack
});
} else {
_loggerUtils.logger.error(String(error), {
component: context || 'errorUtils',
method: 'logError'
});
}
}
/**
* Retry function with exponential backoff
* Re-exports retryAsync for backward compatibility
* @deprecated Use retryAsync from asyncUtils instead
*/
//# sourceMappingURL=errorUtils.js.map