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.errorodata.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:
- Importar funciones de error handler
- Reemplazar
try-catchgenérico conhandleToolError() - Agregar validación con
validateRequired() - Agregar
handleApiResponse()después de llamadas API - 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.