@gp_jcisneros/errors
Version:
Error handling utilities for GreenPay microservices
560 lines (409 loc) • 15.7 kB
Markdown
# @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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