UNPKG

@gp_jcisneros/errors

Version:

Error handling utilities for GreenPay microservices

560 lines (409 loc) 15.7 kB
# @greenpay/errors Biblioteca de manejo de errores estandarizada para microservicios GreenPay con campos requeridos para transformación empresarial. ## 📦 Instalación **Requisitos:** Node.js 22.x o superior ```bash npm install @greenpay/errors ``` ## 🚀 Uso Rápido ```javascript const { CustomError, HttpError, ValidationError, DatabaseError, AWSError, IntegrationError, } = require('@greenpay/errors'); // Crear un error personalizado con campos requeridos const error = new CustomError('Algo salió mal', 400, { errorCode: 'GP_VALIDATION_ERROR', description: 'Error de validación en los datos de entrada', integration: 'transaction-service' }); // Verificar campos requeridos console.log('Tiene campos requeridos:', error.hasRequiredFields()); console.log('Campos requeridos:', error.getRequiredFields()); // Convertir a formato estándar const standardFormat = error.toStandardFormat(); ``` ## 🏗️ Arquitectura de Errores Este NPM está diseñado para estandarizar el manejo de errores en todos los módulos de GreenPay con **campos requeridos** para facilitar la transformación empresarial. ### **Campos Requeridos Estandarizados:** Todos los errores incluyen tres campos requeridos para estandarización: - **`errorCode`**: Código alfanumérico que identifica el error - **`description`**: Descripción detallada del error - **`integration`**: Nombre del módulo de integración donde se está usando el error ### **Flujo de Trabajo:** ```javascript // 1. Crear error con campos requeridos const error = new CustomError('Error de validación', 400, { errorCode: 'GP_VALIDATION_ERROR', description: 'Error de validación en los datos de entrada', integration: 'transaction-service' }); // 2. Verificar que tiene todos los campos requeridos if (error.hasRequiredFields()) { const fields = error.getRequiredFields(); // Los campos están disponibles para transformación empresarial console.log('Código de error:', fields.errorCode); console.log('Descripción:', fields.description); console.log('Integración:', fields.integration); } // 3. Convertir a formato estándar para APIs const response = error.toStandardFormat(); ``` ## 📚 Clases de Error ### CustomError Clase base con **campos requeridos estandarizados**. #### Campos Requeridos El `CustomError` incluye tres campos requeridos para estandarización: - **`errorCode`**: Código alfanumérico que identifica el error - **`description`**: Descripción detallada del error - **`integration`**: Nombre del módulo de integración donde se está usando el error ```javascript const { CustomError } = require('@greenpay/errors'); // Error básico const error = new CustomError('Mensaje de error', 500); // Error con campos requeridos const errorWithRequired = new CustomError('Error de validación', 400, { errorCode: 'GP_VALIDATION_ERROR', description: 'Error de validación en los datos de entrada', integration: 'transaction-service' }); // Usando métodos setter const errorWithSetters = new CustomError('Error de base de datos', 500); errorWithSetters .setErrorCode('GP_DB_CONNECTION_ERROR') .setDescription('Error de conexión a la base de datos') .setIntegration('database-service'); // Usando setRequiredFields para establecer todos a la vez const errorWithSetRequired = new CustomError('Error de autenticación', 401); errorWithSetRequired.setRequiredFields( 'GP_AUTH_ERROR', 'Error de autenticación del usuario', 'auth-service' ); // Validar campos requeridos console.log('Tiene campos requeridos:', errorWithRequired.hasRequiredFields()); console.log('Campos requeridos:', errorWithRequired.getRequiredFields()); // Convertir a formato estándar const standardFormat = errorWithRequired.toStandardFormat(); // { // code: 400, // status: 'failed', // message: 'Error de validación', // error_code: 'GP_VALIDATION_ERROR', // description: 'Error de validación en los datos de entrada', // integration: 'transaction-service' // } ``` ### HttpError Errores HTTP predefinidos con campos requeridos automáticos. ```javascript const { HttpError } = require('@greenpay/errors'); // Errores comunes con campos requeridos automáticos const badRequest = HttpError.badRequest('Datos inválidos'); // errorCode: 'HTTP_400', integration: 'http-service' const unauthorized = HttpError.unauthorized('Token inválido'); // errorCode: 'HTTP_401', integration: 'http-service' const notFound = HttpError.notFound('Usuario no encontrado'); // errorCode: 'HTTP_404', integration: 'http-service' const conflict = HttpError.conflict('Usuario ya existe'); // errorCode: 'HTTP_409', integration: 'http-service' const internalError = HttpError.internalServerError('Error interno'); // errorCode: 'HTTP_500', integration: 'http-service' // Verificar campos requeridos console.log('Tiene campos requeridos:', badRequest.hasRequiredFields()); ``` ### ValidationError Errores específicos para validación de datos con campos requeridos automáticos. ```javascript const { ValidationError } = require('@greenpay/errors'); // Errores de validación con campos requeridos automáticos const requiredError = ValidationError.required('email'); // errorCode: 'VALIDATION_EMAIL', integration: 'validation-service' const emailError = ValidationError.invalidEmail('email', 'invalid@'); // errorCode: 'VALIDATION_EMAIL', integration: 'validation-service' const lengthError = ValidationError.minLength('password', 8, '123'); // errorCode: 'VALIDATION_PASSWORD', integration: 'validation-service' const formatError = ValidationError.invalidFormat('phone', 'XXX-XXX-XXXX', '123'); // errorCode: 'VALIDATION_PHONE', integration: 'validation-service' // Error personalizado para un campo const customError = ValidationError.forField('age', 'Debe ser mayor de 18', 15); // errorCode: 'VALIDATION_AGE', integration: 'validation-service' // Obtener detalles de validación const details = requiredError.getValidationDetails(); ``` ### DatabaseError Errores específicos para operaciones de base de datos con campos requeridos automáticos. ```javascript const { DatabaseError } = require('@greenpay/errors'); // Errores de base de datos con campos requeridos automáticos const connectionError = DatabaseError.connection('Conexión fallida'); // errorCode: 'DB_CONNECT', integration: 'database-service' const notFoundError = DatabaseError.notFound('users'); // errorCode: 'DB_GET', integration: 'database-service' const duplicateError = DatabaseError.duplicateKey('users', 'email'); // errorCode: 'DB_INSERT', integration: 'database-service' const insertError = DatabaseError.insert('Error al insertar', 'users'); // errorCode: 'DB_INSERT', integration: 'database-service' const updateError = DatabaseError.update('Error al actualizar', 'users'); // errorCode: 'DB_UPDATE', integration: 'database-service' const deleteError = DatabaseError.delete('Error al eliminar', 'users'); // errorCode: 'DB_DELETE', integration: 'database-service' const constraintError = DatabaseError.constraintViolation('Constraint failed', 'users'); // errorCode: 'DB_CONSTRAINT', integration: 'database-service' // Obtener detalles de base de datos const details = connectionError.getDatabaseDetails(); ``` ### AWSError Errores específicos para servicios AWS con campos requeridos automáticos. ```javascript const { AWSError } = require('@greenpay/errors'); // Errores de AWS con campos requeridos automáticos const dynamoError = AWSError.dynamoDB('ConditionalCheckFailedException', 'Condition check failed'); // errorCode: 'AWS_DYNAMODB', integration: 'aws-service' const s3Error = AWSError.s3('NoSuchKey', 'Object not found'); // errorCode: 'AWS_S3', integration: 'aws-service' const lambdaError = AWSError.lambda('ResourceNotFoundException', 'Function not found'); // errorCode: 'AWS_LAMBDA', integration: 'aws-service' const sqsError = AWSError.sqs('QueueDoesNotExist', 'Queue not found'); // errorCode: 'AWS_SQS', integration: 'aws-service' // Error para servicio personalizado const ec2Error = AWSError.forService('EC2', 'InvalidInstanceID.NotFound', 'Instance not found'); // errorCode: 'AWS_EC2', integration: 'aws-service' // Obtener detalles de AWS const details = dynamoError.getAWSDetails(); ``` ### IntegrationError Errores específicos para integraciones externas con campos requeridos automáticos. ```javascript const { IntegrationError } = require('@greenpay/errors'); // Errores de integraciones específicas con campos requeridos automáticos const cybersourceError = IntegrationError.cybersource('Card stolen', 'CYBERSOURCE_05'); // errorCode: 'CYBERSOURCE_05', integration: 'cybersource' const stripeError = IntegrationError.stripe('Card declined', 'STRIPE_card_declined'); // errorCode: 'STRIPE_card_declined', integration: 'stripe' const adyenError = IntegrationError.adyen('Payment failed', 'ADYEN_123'); // errorCode: 'ADYEN_123', integration: 'adyen' // Error personalizado para integración const customIntegrationError = IntegrationError.custom('Custom error', 'CUSTOM_001', 'custom-service'); // errorCode: 'CUSTOM_001', integration: 'custom-service' // Obtener detalles de integración const details = cybersourceError.getIntegrationDetails(); ``` ## 📋 Ejemplos de Uso ### Validación con Errores Estandarizados ```javascript const { ValidationError } = require('@greenpay/errors'); function validateUserData(userData) { const errors = []; if (!userData.email) { errors.push(ValidationError.required('email')); } else if (!isValidEmail(userData.email)) { errors.push(ValidationError.invalidEmail('email', userData.email)); } if (!userData.password) { errors.push(ValidationError.required('password')); } else if (userData.password.length < 8) { errors.push(ValidationError.minLength('password', 8, userData.password)); } // Verificar que todos los errores tienen campos requeridos const validErrors = errors.filter(error => error.hasRequiredFields()); return validErrors; } ``` ### Error de Base de Datos ```javascript const { DatabaseError } = require('@greenpay/errors'); async function getUserById(userId) { try { const user = await db.users.findById(userId); if (!user) { throw DatabaseError.notFound('users'); } return user; } catch (error) { // El error ya tiene campos requeridos automáticos console.log('Campos requeridos:', error.getRequiredFields()); throw error; } } ``` ### Error de AWS ```javascript const { AWSError } = require('@greenpay/errors'); async function getS3Object(bucket, key) { try { const result = await s3.getObject({ Bucket: bucket, Key: key }).promise(); return result.Body; } catch (error) { if (error.code === 'NoSuchKey') { throw AWSError.s3('NoSuchKey', 'Object not found'); } throw error; } } ``` ### Error de Integración ```javascript const { IntegrationError } = require('@greenpay/errors'); async function processPayment(paymentData) { try { const response = await cybersourceAPI.processPayment(paymentData); if (response.error) { throw IntegrationError.cybersource( response.error.message, response.error.code, { transactionId: paymentData.transactionId } ); } return response; } catch (error) { // El error ya tiene campos requeridos automáticos console.log('Código de integración:', error.integrationCode); throw error; } } ``` ### Error HTTP Personalizado ```javascript const { HttpError } = require('@greenpay/errors'); function validateUserAccess(user, resource) { if (!user) { throw HttpError.unauthorized('Usuario no autenticado'); } if (!user.isActive) { throw HttpError.forbidden('Usuario inactivo'); } if (!user.hasPermission(resource)) { throw HttpError.forbidden('Sin permisos para acceder al recurso'); } return true; } ``` ## 🔮 Preparación para Transformación Empresarial ### **Campos requeridos disponibles para mapeo:** ```javascript const error = new CustomError('Error de validación', 400, { errorCode: 'GP_VALIDATION_ERROR', description: 'Error de validación en los datos de entrada', integration: 'transaction-service' }); // Los campos requeridos están disponibles para transformación console.log(error.getRequiredFields()); // { // errorCode: 'GP_VALIDATION_ERROR', // description: 'Error de validación en los datos de entrada', // integration: 'transaction-service' // } // Verificar si tiene todos los campos requeridos if (error.hasRequiredFields()) { // Listo para transformación empresarial const businessCode = mapToBusinessCode(error.errorCode); console.log('Código de negocio:', businessCode); } ``` ### **Formato de respuesta estándar:** ```javascript const standardFormat = error.toStandardFormat(); // { // code: 400, // status: 'failed', // message: 'Error de validación', // error_code: 'GP_VALIDATION_ERROR', // description: 'Error de validación en los datos de entrada', // integration: 'transaction-service' // } ``` ## 🧪 Tests ```bash # Ejecutar tests npm test # Ejecutar tests con coverage npm test -- --coverage # Ejecutar tests en modo watch npm test -- --watch ``` ### **Cobertura de Tests:** - ✅ **59 tests pasando** (100% de éxito) - ✅ **6 suites de tests** completas - ✅ **Todas las clases** con tests completos - ✅ **Campos requeridos** validados - ✅ **Métodos de conversión** testeados ## 🚀 Despliegue Local ### Configuración del Token NPM Para publicar el paquete localmente, primero configura tu token de npm: ```bash # Configurar token de npm (reemplaza TU_TOKEN_AQUI con tu token real) # Token temporal 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 npm config set //registry.npmjs.org/:_authToken=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 # Verificar que estás autenticado npm whoami ``` ### Pasos para Publicar ```bash # 1. Instalar dependencias npm install # 2. Ejecutar tests npm test # 3. Ejecutar linting npm run lint # 4. Verificar qué se va a publicar npm pack # 5. Publicar el paquete npm publish --access public ``` ### Verificar la Publicación ```bash # Verificar que el paquete se publicó correctamente npm info @greenpay/errors # Instalar el paquete para probar npm install @greenpay/errors ``` ### Actualizar Versión ```bash # Incrementar versión patch (1.0.0 -> 1.0.1) npm version patch # Incrementar versión minor (1.0.0 -> 1.1.0) npm version minor # Incrementar versión major (1.0.0 -> 2.0.0) npm version major # Publicar nueva versión npm publish ``` ## 📦 Publicación ```bash # Lint y tests npm run lint npm test # Publicar npm publish ``` ## 🤝 Contribución 1. Fork el repositorio 2. Crea una rama para tu feature (`git checkout -b feature/nueva-funcionalidad`) 3. Commit tus cambios (`git commit -am 'Agregar nueva funcionalidad'`) 4. Push a la rama (`git push origin feature/nueva-funcionalidad`) 5. Crea un Pull Request ## 📄 Licencia MIT License - ver [LICENSE](LICENSE) para detalles. ## 🆘 Soporte Para soporte técnico, contacta al equipo de GreenPay o crea un issue en el repositorio. --- ## 🎯 **Estado del Proyecto** ### **✅ Completado:** - ✅ **Campos requeridos estandarizados** en todas las clases - ✅ **59 tests pasando** (100% de éxito) - ✅ **Linter sin errores** - ✅ **Ejemplos funcionando** - ✅ **Documentación actualizada** - ✅ **Preparado para producción** ### **🚀 Listo para:** - ✅ **Publicación en NPM** - ✅ **Integración en otros módulos** - ✅ **Transformación empresarial** - ✅ **Monitoreo y tracking** ### Token de despliegue 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