UNPKG

@energica-city/shared-amplify-utils

Version:

Shared utilities for AWS Amplify projects

319 lines 11.2 kB
// rest/RestErrors.ts import { throwError, createErrorContext } from '../../error'; /** * REST-specific error codes for standardized error classification * * Provides consistent error codes for common REST API error scenarios * that map to appropriate HTTP status codes. */ export const RestErrorCodes = { /** Request validation failed - malformed or invalid data */ VALIDATION_ERROR: 'VALIDATION_ERROR', /** Authentication required or invalid credentials */ AUTHENTICATION_ERROR: 'AUTHENTICATION_ERROR', /** Access denied - valid credentials but insufficient permissions */ AUTHORIZATION_ERROR: 'AUTHORIZATION_ERROR', /** Requested resource not found */ NOT_FOUND: 'NOT_FOUND', /** Resource conflict - duplicate or constraint violation */ CONFLICT: 'CONFLICT', /** Malformed request or invalid parameters */ BAD_REQUEST: 'BAD_REQUEST', /** Internal server error - unexpected failure */ INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR', /** Service temporarily unavailable */ SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE', /** Rate limit exceeded */ TOO_MANY_REQUESTS: 'TOO_MANY_REQUESTS', }; /** * Creates a REST-specific error with proper status code and error code * * Central function for creating standardized REST errors with * appropriate HTTP status codes and structured context. * * @param statusCode - HTTP status code for the error * @param code - REST error code from RestErrorCodes * @param message - Human-readable error message * @param context - Additional context and original error information * @throws Always throws - this function never returns */ export function throwRestError(statusCode, code, message, context) { const { originalError, ...errorContext } = context || {}; const fullContext = createErrorContext({ ...errorContext, statusCode, code, originalError, }); throwError(message, fullContext); } /** * Convenience functions for common REST error scenarios * * Provides pre-configured error throwing functions for standard * HTTP error cases with appropriate status codes and error codes. */ export const RestErrors = { /** * Throws a validation error (400 Bad Request) * * Used when request data fails validation or is malformed. * * @param message - Description of the validation failure * @param context - Request context and validation details * @param originalError - Original validation error if available * @throws Always throws validation error */ validation(message, context, originalError) { throwRestError(400, 'VALIDATION_ERROR', message, { ...context, originalError, }); }, /** * Throws an authentication error (401 Unauthorized) * * Used when authentication is required or credentials are invalid. * * @param message - Description of the authentication failure * @param context - Request context and authentication details * @param originalError - Original authentication error if available * @throws Always throws authentication error */ authentication(message, context, originalError) { throwRestError(401, 'AUTHENTICATION_ERROR', message, { ...context, originalError, }); }, /** * Throws an authorization error (403 Forbidden) * * Used when user is authenticated but lacks required permissions. * * @param message - Description of the authorization failure * @param context - Request context and permission details * @param originalError - Original authorization error if available * @throws Always throws authorization error */ authorization(message, context, originalError) { throwRestError(403, 'AUTHORIZATION_ERROR', message, { ...context, originalError, }); }, /** * Throws a not found error (404 Not Found) * * Used when requested resource does not exist. * * @param message - Description of what was not found * @param context - Request context and resource details * @param originalError - Original lookup error if available * @throws Always throws not found error */ notFound(message, context, originalError) { throwRestError(404, 'NOT_FOUND', message, { ...context, originalError, }); }, /** * Throws a conflict error (409 Conflict) * * Used when request conflicts with current resource state. * * @param message - Description of the conflict * @param context - Request context and conflict details * @param originalError - Original conflict error if available * @throws Always throws conflict error */ conflict(message, context, originalError) { throwRestError(409, 'CONFLICT', message, { ...context, originalError, }); }, /** * Throws a bad request error (400 Bad Request) * * Used when request is malformed or contains invalid parameters. * * @param message - Description of the bad request * @param context - Request context and parameter details * @param originalError - Original parsing error if available * @throws Always throws bad request error */ badRequest(message, context, originalError) { throwRestError(400, 'BAD_REQUEST', message, { ...context, originalError, }); }, /** * Throws a rate limit error (429 Too Many Requests) * * Used when client has exceeded rate limiting thresholds. * * @param message - Description of the rate limit violation * @param context - Request context and rate limit details * @param originalError - Original rate limiting error if available * @throws Always throws rate limit error */ tooManyRequests(message, context, originalError) { throwRestError(429, 'TOO_MANY_REQUESTS', message, { ...context, originalError, }); }, /** * Throws a service unavailable error (503 Service Unavailable) * * Used when service is temporarily unavailable or under maintenance. * * @param message - Description of the service unavailability * @param context - Request context and service status details * @param originalError - Original service error if available * @throws Always throws service unavailable error */ serviceUnavailable(message, context, originalError) { throwRestError(503, 'SERVICE_UNAVAILABLE', message, { ...context, originalError, }); }, /** * Throws an internal server error (500 Internal Server Error) * * Used when an unexpected error occurs on the server side. * * @param message - Description of the internal error * @param context - Request context and error details * @param originalError - Original internal error if available * @throws Always throws internal server error */ internal(message, context, originalError) { throwRestError(500, 'INTERNAL_SERVER_ERROR', message, { ...context, originalError, }); }, }; /** * Checks if an error is a REST error with status code * * Type guard function to determine if an unknown error object * is a properly structured REST error with HTTP status code. * * @param error - Unknown error object to check * @returns True if error is a REST error with status code and code properties */ export function isRestError(error) { return (error instanceof Error && 'statusCode' in error && 'code' in error && typeof error.statusCode === 'number' && typeof error.code === 'string'); } /** * Maps REST error codes to HTTP status codes and response formatting * * Provides centralized mapping between REST error codes and their * corresponding HTTP status codes for consistent error handling. */ export const RestErrorMapping = { [RestErrorCodes.VALIDATION_ERROR]: { statusCode: 400, title: 'Validation Error', description: 'Request data failed validation', }, [RestErrorCodes.AUTHENTICATION_ERROR]: { statusCode: 401, title: 'Authentication Error', description: 'Authentication required or invalid credentials', }, [RestErrorCodes.AUTHORIZATION_ERROR]: { statusCode: 403, title: 'Authorization Error', description: 'Access denied - insufficient permissions', }, [RestErrorCodes.NOT_FOUND]: { statusCode: 404, title: 'Not Found', description: 'Requested resource not found', }, [RestErrorCodes.CONFLICT]: { statusCode: 409, title: 'Conflict', description: 'Resource conflict or constraint violation', }, [RestErrorCodes.BAD_REQUEST]: { statusCode: 400, title: 'Bad Request', description: 'Malformed request or invalid parameters', }, [RestErrorCodes.TOO_MANY_REQUESTS]: { statusCode: 429, title: 'Too Many Requests', description: 'Rate limit exceeded', }, [RestErrorCodes.INTERNAL_SERVER_ERROR]: { statusCode: 500, title: 'Internal Server Error', description: 'Unexpected server error occurred', }, [RestErrorCodes.SERVICE_UNAVAILABLE]: { statusCode: 503, title: 'Service Unavailable', description: 'Service temporarily unavailable', }, }; /** * Creates a standardized error response for REST errors * * Converts REST errors into properly formatted API Gateway responses * with consistent structure and appropriate HTTP status codes. * * @param error - REST error with code and context * @param requestId - Request ID for response tracking * @returns API Gateway response object with error details */ export function createRestErrorResponse(error, requestId) { const mapping = RestErrorMapping[error.code]; const statusCode = error.statusCode || mapping?.statusCode || 500; return { statusCode, headers: { 'Content-Type': 'application/json', 'X-Request-ID': requestId, }, body: JSON.stringify({ success: false, error: { code: error.code, message: error.message, title: mapping?.title || 'Error', statusCode, }, context: error.context, meta: { timestamp: new Date().toISOString(), requestId, }, }), }; } /** * Checks if an error code is a known REST error code * * Determines if an error code is recognized and can be * handled gracefully by the error response system. * * @param code - Error code to check * @returns True if code is a known REST error code */ export function isKnownRestErrorCode(code) { return Object.values(RestErrorCodes).includes(code); } //# sourceMappingURL=RestErrors.js.map