UNPKG

pagamio-frontend-commons-lib

Version:

Pagamio library for Frontend reusable components like the form engine and table container

191 lines (190 loc) 6.46 kB
/** * Different types of errors that can occur during authentication */ export var AuthErrorType; (function (AuthErrorType) { AuthErrorType["NETWORK"] = "NETWORK"; AuthErrorType["AUTHENTICATION"] = "AUTHENTICATION"; AuthErrorType["SERVER"] = "SERVER"; AuthErrorType["VALIDATION"] = "VALIDATION"; AuthErrorType["UNKNOWN"] = "UNKNOWN"; })(AuthErrorType || (AuthErrorType = {})); /** * Network error indicators */ const NETWORK_ERROR_INDICATORS = { ERROR_MESSAGES: ['NetworkError', 'Failed to fetch', 'ERR_NETWORK', 'ERR_INTERNET_DISCONNECTED'], STRING_INDICATORS: [ 'network error', 'connection failed', 'timeout', 'unreachable', 'no internet', 'connection refused', ], }; /** * Authentication error indicators */ const AUTH_ERROR_INDICATORS = ['invalid credentials', 'invalid username', 'invalid password', 'unauthorized']; /** * Common network error message */ const NETWORK_ERROR_MESSAGE = 'Unable to connect. Please check your internet connection and try again.'; /** * Checks if the error is a network-related error */ function isNetworkError(error) { // Handle fetch/network errors if (error instanceof TypeError && error.message.includes('fetch')) { return { type: AuthErrorType.NETWORK, message: NETWORK_ERROR_MESSAGE, originalError: error, }; } // Handle network timeout if (error instanceof Error && error.name === 'AbortError') { return { type: AuthErrorType.NETWORK, message: 'Connection timed out. Please check your internet connection and try again.', originalError: error, }; } // Handle offline detection if (!navigator.onLine) { return { type: AuthErrorType.NETWORK, message: 'You appear to be offline. Please check your internet connection and try again.', originalError: error instanceof Error ? error : undefined, }; } // Handle Error objects with network indicators if (error instanceof Error) { const hasNetworkIndicator = NETWORK_ERROR_INDICATORS.ERROR_MESSAGES.some((indicator) => error.message.includes(indicator)); if (hasNetworkIndicator) { return { type: AuthErrorType.NETWORK, message: NETWORK_ERROR_MESSAGE, originalError: error, }; } } // Handle string errors with network indicators if (typeof error === 'string') { const lowercaseError = error.toLowerCase(); const hasNetworkIndicator = NETWORK_ERROR_INDICATORS.STRING_INDICATORS.some((indicator) => lowercaseError.includes(indicator)); if (hasNetworkIndicator) { return { type: AuthErrorType.NETWORK, message: NETWORK_ERROR_MESSAGE, }; } } return null; } /** * Checks if the error is an authentication-related custom error */ function isCustomAuthError(customError) { if (customError.code !== 'UNKNOWN_ERROR') { return false; } const message = customError.message.toLowerCase(); return AUTH_ERROR_INDICATORS.some((indicator) => message.includes(indicator)); } /** * Creates error info object */ function createErrorInfo(type, message, originalError) { return { type, message, originalError: originalError instanceof Error ? originalError : undefined, }; } /** * Handles custom server error format */ function handleCustomError(error) { // Handle authentication errors if (isCustomAuthError(error)) { return createErrorInfo(AuthErrorType.AUTHENTICATION, 'Invalid credentials. Please check your username and password.', error); } // Handle validation errors if (error.code === 'VALIDATION_ERROR') { return createErrorInfo(AuthErrorType.VALIDATION, error.message || 'Please check your input and try again.', error); } // For other custom errors, use the server message return createErrorInfo(AuthErrorType.UNKNOWN, error.message || 'An error occurred. Please try again.', error); } /** * Maps HTTP status to error type and message */ function getHttpErrorMapping(status) { if (status === 401 || status === 403) { return { type: AuthErrorType.AUTHENTICATION, message: 'Invalid credentials. Please check your username and password.', }; } if (status === 422) { return { type: AuthErrorType.VALIDATION, message: 'Please check your input and try again.', }; } if (status === 500 || status === 502 || status === 503) { return { type: AuthErrorType.SERVER, message: 'Server is temporarily unavailable. Please try again later.', }; } if (status >= 500) { return { type: AuthErrorType.SERVER, message: 'Server error occurred. Please try again later.', }; } return null; } /** * Handles HTTP status code errors */ function handleHttpError(httpError) { const mapping = getHttpErrorMapping(httpError.status); if (!mapping) { return null; } const message = httpError.status === 422 && httpError.message ? httpError.message : mapping.message; return createErrorInfo(mapping.type, message, httpError); } /** * Detects the type of error and returns appropriate user-friendly message */ export function detectErrorType(error) { // Check for network errors first const networkError = isNetworkError(error); if (networkError) { return networkError; } // Handle custom error format if (error && typeof error === 'object' && 'code' in error && 'message' in error) { const customError = error; return handleCustomError(customError); } // Handle HTTP errors if (error && typeof error === 'object' && 'status' in error) { const httpError = error; const httpResult = handleHttpError(httpError); if (httpResult) { return httpResult; } } // Handle generic Error objects if (error instanceof Error) { return createErrorInfo(AuthErrorType.UNKNOWN, error.message || 'An unexpected error occurred. Please try again.', error); } // Fallback return createErrorInfo(AuthErrorType.UNKNOWN, 'An unexpected error occurred. Please try again.'); }