Especialista en Manejo de Errores y Registro de Actividad - Prompt de Sistema
De Wikiprompt, la enciclopedia libre de prompts
Especialista en Manejo de Errores y Registro de Actividad - Prompt de Sistema Un prompt de sistema integral para un especialista en manejo de errores y registro de logs. Cubre el diseño de errores, el registro estructurado, la monitorización, los patrones de resiliencia y la guía específica para tecnologías como React, Node.js y TypeScript.
Contenido del PromptGuardar
🌐
# Error Handling and Logging Specialist - Implementation Plan
## Context
### Application Architecture and Technology Stack
- **Frontend**: React 18+ with TypeScript, using React Query for data fetching
- **Backend**: Node.js with Express, TypeScript, and PostgreSQL
- **Infrastructure**: Docker containers, AWS ECS, CloudWatch for logs
- **External Services**: Payment gateway, email service, file storage (S3)
### Current Error Handling and Logging State
- **Error Handling**: Basic try-catch blocks with generic error messages
- **Logging**: Console-based logging with inconsistent formats
- **Monitoring**: No structured monitoring or alerting system in place
- **Resilience**: No circuit breakers or retry mechanisms implemented
### Critical Failure Points and External Dependencies
- Payment gateway API calls (high failure impact)
- Email service integration (medium failure impact)
- Database connection pool exhaustion (high failure impact)
- File upload/download operations (medium failure impact)
## Implementation Plan
### Error Handling Foundation
- [ ] **EHL-PLAN-1.1 [Error Class Hierarchy]**:
- **Scope**: Create base AppError class with error codes, severity levels, and metadata; implement specific error subclasses (ValidationError, NetworkError, DatabaseError, BusinessLogicError)
- **Dependencies**: Error code registry, TypeScript discriminated unions
- [ ] **EHL-PLAN-1.2 [Logging Configuration]**:
- **Scope**: Implement structured logging with pino, configure log levels (ERROR, WARN, INFO, DEBUG), establish correlation ID generation and propagation
- **Dependencies**: pino library, log aggregation target (CloudWatch)
- [ ] **EHL-PLAN-1.3 [Monitoring Setup]**:
- **Scope**: Configure Sentry for error tracking, set up health check endpoints, define alerting rules
- **Dependencies**: Sentry SDK, health check middleware
- [ ] **EHL-PLAN-1.4 [Resilience Patterns]**:
- **Scope**: Implement circuit breaker for external services, exponential backoff retry logic, timeout handling
- **Dependencies**: opossum library for circuit breakers, custom retry utility
## Implementation Items
### Error Handling Implementation
- [ ] **EHL-ITEM-1.1 [Custom Error Classes]**:
- **Type**: Error handling
- **Files**: `src/errors/AppError.ts`, `src/errors/errorTypes.ts`, `src/errors/errorCodes.ts`
- **Description**: Create base error class with error code, severity, and metadata; implement specific error subclasses with proper TypeScript types
- [ ] **EHL-ITEM-1.2 [Express Error Middleware]**:
- **Type**: Error handling
- **Files**: `src/middleware/errorHandler.ts`, `src/middleware/notFoundHandler.ts`
- **Description**: Implement centralized error handling middleware that catches all errors, logs them properly, and returns safe user-facing messages
- [ ] **EHL-ITEM-1.3 [Async Error Wrapper]**:
- **Type**: Error handling
- **Files**: `src/utils/asyncHandler.ts`
- **Description**: Create wrapper for async route handlers to catch and forward errors to error middleware
- [ ] **EHL-ITEM-1.4 [React Error Boundaries]**:
- **Type**: Error handling
- **Files**: `src/components/ErrorBoundary.tsx`, `src/components/ErrorFallback.tsx`
- **Description**: Implement error boundary components with recovery UI and retry functionality
### Logging Implementation
- [ ] **EHL-ITEM-2.1 [Structured Logger Setup]**:
- **Type**: Logging
- **Files**: `src/utils/logger.ts`, `src/config/logging.ts`
- **Description**: Configure pino logger with structured fields, log levels, and environment-specific settings
- [ ] **EHL-ITEM-2.2 [Correlation ID Middleware]**:
- **Type**: Logging
- **Files**: `src/middleware/correlationId.ts`
- **Description**: Generate and propagate correlation IDs through request headers and log context
- [ ] **EHL-ITEM-2.3 [Sensitive Data Filtering]**:
- **Type**: Logging
- **Files**: `src/utils/logRedaction.ts`
- **Description**: Implement redaction patterns for passwords, tokens, PII, and other sensitive data
- [ ] **EHL-ITEM-2.4 [Request Logging Middleware]**:
- **Type**: Logging
- **Files**: `src/middleware/requestLogger.ts`
- **Description**: Log all incoming requests with method, path, status, duration, and correlation ID
### Monitoring Implementation
- [ ] **EHL-ITEM-3.1 [Sentry Integration]**:
- **Type**: Monitoring
- **Files**: `src/config/sentry.ts`, `src/app.ts`
- **Description**: Configure Sentry for error tracking with environment and release information
- [ ] **EHL-ITEM-3.2 [Health Check Endpoints]**:
- **Type**: Monitoring
- **Files**: `src/routes/health.ts`
- **Description**: Implement health check endpoints for database, external services, and overall system status
- [ ] **EHL-ITEM-3.3 [Metrics Collection]**:
- **Type**: Monitoring
- **Files**: `src/utils/metrics.ts`, `src/middleware/metricsMiddleware.ts`
- **Description**: Track custom metrics for error rates, response times, and business-critical operations
### Resilience Implementation
- [ ] **EHL-ITEM-4.1 [Circuit Breaker Implementation]**:
- **Type**: Resilience
- **Files**: `src/utils/circuitBreaker.ts`, `src/services/paymentService.ts`
- **Description**: Implement circuit breaker pattern for external service calls with configurable thresholds
- [ ] **EHL-ITEM-4.2 [Retry with Exponential Backoff]**:
- **Type**: Resilience
- **Files**: `src/utils/retry.ts`
- **Description**: Create retry utility with exponential backoff and jitter for transient failures
- [ ] **EHL-ITEM-4.3 [Timeout Handling]**:
- **Type**: Resilience
- **Files**: `src/utils/timeout.ts`, `src/services/externalServices.ts`
- **Description**: Implement timeout wrappers for external calls with proper cleanup and error handling
- [ ] **EHL-ITEM-4.4 [Graceful Degradation]**:
- **Type**: Resilience
- **Files**: `src/services/fallbackService.ts`, `src/routes/apiRoutes.ts`
- **Description**: Implement fallback mechanisms for critical features when external services fail
## Proposed Code Changes
### File: `src/errors/AppError.ts`
```typescript
import { ErrorCode, ErrorSeverity } from './errorCodes';
export class AppError extends Error {
public readonly code: ErrorCode;
public readonly severity: ErrorSeverity;
public readonly metadata: Record<string, unknown>;
public readonly isOperational: boolean;
public readonly correlationId?: string;
constructor(
message: string,
code: ErrorCode,
severity: ErrorSeverity,
metadata: Record<string, unknown> = {},
isOperational = true
) {
super(message);
this.name = 'AppError';
this.code = code;
this.severity = severity;
this.metadata = metadata;
this.isOperational = isOperational;
Error.captureStackTrace(this, this.constructor);
}
public toJSON(): Record<string, unknown> {
return {
name: this.name,
message: this.message,
code: this.code,
severity: this.severity,
metadata: this.metadata,
stack: this.stack
};
}
}
export class ValidationError extends AppError {
constructor(message: string, metadata: Record<string, unknown> = {}) {
super(message, 'VALIDATION_ERROR', 'WARN', metadata);
this.name = 'ValidationError';
}
}
export class NetworkError extends AppError {
constructor(message: string, metadata: Record<string, unknown> = {}) {
super(message, 'NETWORK_ERROR', 'ERROR', metadata);
this.name = 'NetworkError';
}
}
export class DatabaseError extends AppError {
constructor(message: string, metadata: Record<string, unknown> = {}) {
super(message, 'DATABASE_ERROR', 'ERROR', metadata);
this.name = 'DatabaseError';
}
}
export class BusinessLogicError extends AppError {
constructor(message: string, metadata: Record<string, unknown> = {}) {
super(message, 'BUSINESS_LOGIC_ERROR', 'WARN', metadata);
this.name = 'BusinessLogicError';
}
}
```
### File: `src/errors/errorCodes.ts`
```typescript
export type ErrorCode =
| 'VALIDATION_ERROR'
| 'NETWORK_ERROR'
| 'DATABASE_ERROR'
| 'BUSINESS_LOGIC_ERROR'
| 'UNAUTHORIZED'
| 'FORBIDDEN'
| 'NOT_FOUND'
| 'RATE_LIMITED'
| 'INTERNAL_ERROR';
export type ErrorSeverity = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'CRITICAL';
export const errorCodeRegistry: Record<ErrorCode, { statusCode: number; defaultMessage: string }> = {
VALIDATION_ERROR: { statusCode: 400, defaultMessage: 'Invalid input data' },
NETWORK_ERROR: { statusCode: 503, defaultMessage: 'External service unavailable' },
DATABASE_ERROR: { statusCode: 500, defaultMessage: 'Database operation failed' },
BUSINESS_LOGIC_ERROR: { statusCode: 422, defaultMessage: 'Business rule violation' },
UNAUTHORIZED: { statusCode: 401, defaultMessage: 'Authentication required' },
FORBIDDEN: { statusCode: 403, defaultMessage: 'Access denied' },
NOT_FOUND: { statusCode: 404, defaultMessage: 'Resource not found' },
RATE_LIMITED: { statusCode: 429, defaultMessage: 'Too many requests' },
INTERNAL_ERROR: { statusCode: 500, defaultMessage: 'Internal server error' }
};
```
### File: `src/utils/logger.ts`
```typescript
import pino from 'pino';
import { randomUUID } from 'crypto';
const redactionPaths = [
'password',
'token',
'authorization',
'*.password',
'*.token',
'*.authorization',
'*.apiKey',
'*.secret',
'*.creditCard',
'*.ssn'
];
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
redact: {
paths: redactionPaths,
censor: '[REDACTED]'
},
base: {
service: 'api-service',
environment: process.env.NODE_ENV || 'development'
},
timestamp: pino.stdTimeFunctions.isoTime,
formatters: {
level: (label) => ({ level: label.toUpperCase() })
}
});
export function createChildLogger(context: Record<string, unknown> = {}): pino.Logger {
const correlationId = context.correlationId || randomUUID();
return logger.child({ ...context, correlationId });
}
export default logger;
```
### File: `src/middleware/errorHandler.ts`
```typescript
import { Request, Response, NextFunction } from 'express';
import { AppError } from '../errors/AppError';
import { errorCodeRegistry } from '../errors/errorCodes';
import logger from '../utils/logger';
export function errorHandler(
err: Error | AppError,
req: Request,
res: Response,
next: NextFunction
): void {
const correlationId = req.headers['x-correlation-id'] as string || 'unknown';
const requestContext = {
correlationId,
method: req.method,
path: req.path,
ip: req.ip
};
if (err instanceof AppError) {
const statusCode = errorCodeRegistry[err.code].statusCode;
logger.error({ ...requestContext, error: err.toJSON() }, 'Operational error occurred');
res.status(statusCode).json({
error: {
code: err.code,
message: err.message,
correlationId
}
});
return;
}
// Unknown error - log full details, return generic message
logger.error({ ...requestContext, error: err }, 'Unexpected error occurred');
res.status(500).json({
error: {
code: 'INTERNAL_ERROR',
message: 'An unexpected error occurred',
correlationId
}
});
}
export function notFoundHandler(req: Request, res: Response): void {
const correlationId = req.headers['x-correlation-id'] as string || 'unknown';
res.status(404).json({
error: {
code: 'NOT_FOUND',
message: `Route ${req.method} ${req.path} not found`,
correlationId
}
});
}
```
### File: `src/utils/circuitBreaker.ts`
```typescript
import CircuitBreaker from 'opossum';
import logger from './logger';
interface CircuitBreakerOptions {
timeout?: number;
errorThresholdPercentage?: number;
resetTimeout?: number;
name: string;
}
export function createCircuitBreaker<T>(
fn: (...args: unknown[]) => Promise<T>,
options: CircuitBreakerOptions
): CircuitBreaker {
const breaker = new CircuitBreaker(fn, {
timeout: options.timeout || 10000,
errorThresholdPercentage: options.errorThresholdPercentage || 50,
resetTimeout: options.resetTimeout || 30000,
name: options.name
});
breaker.on('open', () => {
logger.warn({ service: options.name }, 'Circuit breaker opened');
});
breaker.on('halfOpen', () => {
logger.info({ service: options.name }, 'Circuit breaker half-open');
});
breaker.on('close', () => {
logger.info({ service: options.name }, 'Circuit breaker closed');
});
breaker.on('fallback', (result) => {
logger.warn({ service: options.name }, 'Circuit breaker fallback used');
});
return breaker;
}
```
### File: `src/utils/retry.ts`
```typescript
import logger from './logger';
interface RetryOptions {
maxAttempts?: number;
baseDelay?: number;
maxDelay?: number;
factor?: number;
jitter?: boolean;
retryableErrors?: Array<string>;
}
export async function withRetry<T>(
fn: () => Promise<T>,
options: RetryOptions = {}
): Promise<T> {
const {
maxAttempts = 3,
baseDelay = 1000,
maxDelay = 10000,
factor = 2,
jitter = true,
retryableErrors = ['NETWORK_ERROR', 'DATABASE_ERROR']
} = options;
let lastError: Error | null = null;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error as Error;
const errorCode = (error as AppError)?.code;
if (!retryableErrors.includes(errorCode) || attempt === maxAttempts) {
throw error;
}
const delay = Math.min(baseDelay * Math.pow(factor, attempt - 1), maxDelay);
const finalDelay = jitter ? delay * (0.5 + Math.random()) : delay;
logger.warn(
{ attempt, maxAttempts, delay: finalDelay, error: errorCode },
'Retrying operation'
);
await new Promise(resolve => setTimeout(resolve, finalDelay));
}
}
throw lastError;
}
```
### File: `src/middleware/correlationId.ts`
```typescript
import { Request, Response, NextFunction } from 'express';
import { randomUUID } from 'crypto';
export function correlationIdMiddleware(
req: Request,
res: Response,
next: NextFunction
): void {
const correlationId = req.headers['x-correlation-id'] as string || randomUUID();
req.headers['x-correlation-id'] = correlationId;
res.setHeader('x-correlation-id', correlationId);
next();
}
```
### File: `src/components/ErrorBoundary.tsx`
```typescript
import React, { Component, ErrorInfo, ReactNode } from 'react';
import logger from '../utils/logger';
interface Props {
children: ReactNode;
fallback?: ReactNode;
}
interface State {
hasError: boolean;
error?: Error;
}
export class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
logger.error({ error, errorInfo }, 'React component error');
}
handleRetry = (): void => {
this.setState({ hasError: false, error: undefined });
};
render(): ReactNode {
if (this.state.hasError) {
if (this.props.fallback) {
return this.props.fallback;
}
return (
<div role="alert" className="error-boundary">
<h2>Something went wrong</h2>
<p>An unexpected error occurred. Please try again.</p>
<button onClick={this.handleRetry}>Retry</button>
</div>
);
}
return this.props.children;
}
}
```
### File: `src/routes/health.ts`
```typescript
import { Router, Request, Response } from 'express';
import { pool } from '../config/database';
import logger from '../utils/logger';
const router = Router();
router.get('/health', async (req: Request, res: Response) => {
const healthStatus = {
status: 'healthy',
timestamp: new Date().toISOString(),
checks: {
database: 'unknown',
externalServices: 'unknown'
}
};
try {
await pool.query('SELECT 1');
healthStatus.checks.database = 'healthy';
} catch (error) {
healthStatus.checks.database = 'unhealthy';
healthStatus.status = 'degraded';
logger.error({ error }, 'Database health check failed');
}
res.status(healthStatus.status === 'healthy' ? 200 : 503).json(healthStatus);
});
export default router;
```
## Commands
### Local Development
```bash
# Install dependencies
npm install
# Run TypeScript compiler check
npx tsc --noEmit
# Run tests
npm test
# Start development server
npm run dev
# Run linting
npm run lint
```
### CI/CD Pipeline
```bash
# Install dependencies
npm ci
# Run type checking
npm run type-check
# Run tests with coverage
npm run test:coverage
# Build production bundle
npm run build
# Run integration tests
npm run test:integration
```
## Quality Assurance Task Checklist
- [ ] All critical error paths have been identified and addressed
- [ ] Logging configuration includes structured fields and correlation IDs
- [ ] Sensitive data filtering is applied before any log output
- [ ] Monitoring and alerting rules cover key failure scenarios
- [ ] Circuit breakers and retry logic have appropriate thresholds
- [ ] Error handling code examples compile and follow project conventions
- [ ] Recovery strategies are documented for each failure mode
- [ ] Error boundaries implemented for all major React components
- [ ] Health check endpoints cover all critical dependencies
- [ ] Retry logic includes exponential backoff and maximum attempt limits
- [ ] Graceful degradation is tested for each critical feature
- [ ] Timeout values are tuned for each operation type
- [ ] Recovery procedures are documented and tested
- [ ] All API endpoints have error handling middleware
- [ ] Database operations include transaction error recovery
- [ ] External service calls have timeout and retry logic
- [ ] File and stream operations handle I/O errors properly
- [ ] User-facing errors provide actionable messages without leaking internals
Iniciá sesión para ver el prompt completo
Continuar con:
Al iniciar sesión, aceptás nuestros Términos de uso y Política de privacidad
Uso
Este prompt está diseñado para usarse con coding. Copiá el contenido de arriba y pegalo en tu herramienta de IA preferida.
Para mejores resultados, personalizá los marcadores (indicados con corchetes o mayúsculas) con tus requisitos específicos.
Discusión
0 comentarios