Files
agenticSystem/mcp-server/tools/helpers/ERROR_HANDLING.md
2026-04-01 23:16:45 +01:00

6.2 KiB

Error Handling System for Tools

Centralizado error handling para todas las herramientas MCP del servidor.

Características

Manejo consistente de errores - Todas las herramientas retornan el mismo formato Logging automático - Todos los errores se registran en consola Validación de parámetros - Validación requerida y de tipos Detección de errores API - Identifica patrones comunes de error en respuestas Información contextual - Cada error incluye el contexto de dónde ocurrió

Funciones Disponibles

handleToolError(error, context, additionalInfo)

Maneja cualquier error y retorna una respuesta formateada.

import { handleToolError } from "../helpers/errorHandler.js";

try {
    // tu código
} catch (error) {
    return handleToolError(error, 'my_tool', { userId: 123 });
}

Retorna:

{
    "success": false,
    "error": {
        "code": "ECONNREFUSED",
        "message": "connect ECONNREFUSED 127.0.0.1:3000",
        "context": "my_tool",
        "userId": 123
    }
}

handleApiResponse(data, context)

Detecta errores en respuestas de API (busca patrones comunes).

const response = await axios.post(url, payload);

// Detecta automáticamente: error, Error, PHPSyntax, success: false, etc.
const apiError = handleApiResponse(response.data, 'save_module');
if (apiError) return apiError;

validateRequired(params, requiredFields, context)

Valida que los parámetros requeridos estén presentes.

const error = validateRequired(
    { name: "Juan", email: "" },
    ['name', 'email'],
    'create_user'
);
// error porque email está vacío

validateTypes(params, schema, context)

Valida tipos de datos.

const error = validateTypes(
    { age: "25", active: true },
    { age: 'number', active: 'boolean' },
    'create_user'
);
// error porque age es string, no number

createValidator(requiredFields, typeSchema)

Crea una función validadora reutilizable.

const validateUserInput = createValidator(
    ['name', 'email'],
    { age: 'number', active: 'boolean' }
);

// Usar en múltiples lugares
const error = validateUserInput(params, 'create_user');
if (error) return error;

withErrorHandling(handler, toolName)

Envuelve un handler para manejar errores automáticamente.

const safeHandler = withErrorHandling(
    async (params, extra) => {
        // tu código
    },
    'my_tool'
);

safeJsonParse(jsonString, context)

Parse JSON seguro con manejo de errores.

const result = safeJsonParse(jsonString, 'parse_config');
if (!result.success) {
    // result.error contiene el error formateado
    return result.error;
}
const data = result.data;

Patrón Recomendado para Tools

import { z } from "zod";
import axios from "axios";
import { withAuth, getSessionCredentials } from "../../auth/index.js";
import { 
    handleToolError, 
    handleApiResponse, 
    validateRequired 
} from "../helpers/errorHandler.js";

export function registerMyTool(server) {
    server.tool(
        "my_tool",
        "Descripción de la herramienta",
        {
            param1: z.string().describe("Parámetro 1"),
            param2: z.number().describe("Parámetro 2"),
        },
        withAuth(async ({ param1, param2 }, extra) => {
            try {
                // 1. Validar parámetros requeridos
                const validationError = validateRequired(
                    { param1, param2 },
                    ['param1', 'param2'],
                    'my_tool'
                );
                if (validationError) return validationError;

                // 2. Obtener credenciales
                const credentials = getSessionCredentials(extra.sessionId);

                // 3. Hacer llamada API
                const response = await axios.post(url, payload, {
                    headers: { /* ... */ }
                });

                // 4. Verificar respuesta de API
                const apiError = handleApiResponse(response.data, 'my_tool');
                if (apiError) return apiError;

                // 5. Retornar resultado
                return {
                    content: [{
                        type: "text",
                        text: JSON.stringify(response.data, null, 2)
                    }]
                };

            } catch (error) {
                // Los errores se capturan y formatean automáticamente
                return handleToolError(error, 'my_tool', { param1, param2 });
            }
        })
    );
}

Errores Detectados Automáticamente

handleApiResponse() detecta estos patrones en respuestas:

  • data.error o data.Error
  • data.PHPSyntax - Errores de sintaxis PHP
  • data.success === false - Campo success explícito
  • Strings con palabras clave: "error", "fatal", "undefined", "syntax"
  • Respuestas vacías o null

Formato de Error Consistente

Todos los errores retornan este formato:

{
    "success": false,
    "error": {
        "code": "ERROR_CODE",
        "message": "Mensaje descriptivo del error",
        "context": "nombre_del_tool",
        "...": "información adicional"
    }
}

Migración de Tools Existentes

Para actualizar un tool existente:

  1. Importar funciones de error handler
  2. Reemplazar try-catch genérico con handleToolError()
  3. Agregar validación con validateRequired()
  4. Agregar handleApiResponse() después de llamadas API
  5. Pasar información contextual útil a handleToolError()

Ejemplo antes:

try {
    // código
} catch (error) {
    return {
        content: [{ type: "text", text: "Error: " + error.message }],
        isError: true
    };
}

Ejemplo después:

try {
    // código
} catch (error) {
    return handleToolError(error, 'my_tool', { extraInfo: value });
}

Logging

Todos los errores se registran en stderr con contexto:

[Tool Error - save_module] Cannot read property 'website' of undefined
Stack: Error: Cannot read property 'website' of undefined
    at registerSaveModuleTool (/Users/...save.js:45:20)
    ...

Esto facilita debug y auditoría de errores en producción.