Advanced (Actualizado: 3/6/2026)

Patrones de manejo de errores con Claude Code: clasifica fallos en el borde

Guia practica para disenar errores con Claude Code: validacion API, APIs externas, jobs, TypeScript y recuperacion.

Patrones de manejo de errores con Claude Code: clasifica fallos en el borde

Manejar errores no significa llenar el codigo de try-catch. Cuando le pedimos a Claude Code que “arregle el error”, sin mas contexto, el resultado suele ser fragil: todo termina en 500, los logs no dicen si el usuario debe corregir algo, y las integraciones externas quedan mezcladas con fallos internos.

El patron util es este: clasificar el fallo en el borde y declarar la forma de recuperacion. El borde es el punto donde tu aplicacion toca algo menos controlable: una peticion HTTP, un proveedor de pagos, un CRM, un envio de email, un job nocturno, una importacion CSV o una pantalla del frontend. Si el borde esta claro, Claude Code puede implementar reglas concretas: la validacion devuelve 400, un proveedor temporalmente caido se puede reintentar, y un batch fallido deja informacion suficiente para volver a ejecutarlo.

Este articulo explica el enfoque desde cero, pero con una mirada de produccion. Incluye codigo TypeScript copiable, tres casos de uso, errores comunes, prompts para revisar con Claude Code, enlaces oficiales y una llamada a la accion para convertir este patron en formacion o material reutilizable.

Empieza por la recuperacion

Antes de discutir si la clase debe llamarse AppError o DomainError, decide que debe hacer el sistema despues del fallo.

BordeEjemploRespuestaRecuperacion
Validacion de APIEmail invalido, numero fuera de rango, JSON mal formado400El usuario corrige la entrada
API externaPagos, CRM, email o analitica no disponible502 o 503Reintento, pausa o error temporal
Job/BatchReporte nocturno, importacion CSV, notificacionesRegistro interno de falloReejecucion segura, cola de fallos, alerta

Un message legible no basta. Los humanos lo entienden, pero el programa no puede decidir bien. Campos como kind, code, retryable y status permiten que Claude Code revise comportamiento y no solo estilo.

Ejemplo TypeScript ejecutable

El siguiente ejemplo funciona con Node.js 18 o superior. Usa tsx para ejecutar TypeScript directamente y no llama a ninguna API real. La dependencia externa se inyecta como fetcher, por lo que el fallo es reproducible.

npm install -D tsx typescript
npx tsx error-patterns-demo.ts
type Kind = "validation" | "external" | "job";
type AppError = { kind: Kind; code: string; message: string; retryable: boolean; status: number; detail?: unknown };
type Result<T> = { ok: true; value: T } | { ok: false; error: AppError };

const ok = <T>(value: T): Result<T> => ({ ok: true, value });
const fail = <T>(error: AppError): Result<T> => ({ ok: false, error });

function parseUser(body: unknown): Result<{ email: string; age: number }> {
  if (typeof body !== "object" || body === null) {
    return fail({ kind: "validation", code: "BODY_REQUIRED", message: "body must be an object", retryable: false, status: 400 });
  }
  const data = body as Record<string, unknown>;
  if (typeof data.email !== "string" || !data.email.includes("@")) {
    return fail({ kind: "validation", code: "EMAIL_INVALID", message: "email is invalid", retryable: false, status: 400 });
  }
  if (typeof data.age !== "number" || data.age < 13) {
    return fail({ kind: "validation", code: "AGE_INVALID", message: "age must be 13 or greater", retryable: false, status: 400 });
  }
  return ok({ email: data.email, age: data.age });
}

async function callPartner(fetcher: () => Promise<Response>): Promise<Result<{ id: string }>> {
  try {
    const response = await fetcher();
    if (!response.ok) {
      return fail({ kind: "external", code: "PARTNER_HTTP", message: `partner returned ${response.status}`, retryable: response.status >= 500, status: 503 });
    }
    const json = (await response.json()) as { id?: unknown };
    if (typeof json.id !== "string") {
      return fail({ kind: "external", code: "PARTNER_PAYLOAD", message: "partner payload is invalid", retryable: false, status: 502, detail: json });
    }
    return ok({ id: json.id });
  } catch (error) {
    return fail({ kind: "external", code: "PARTNER_UNREACHABLE", message: "partner is unreachable", retryable: true, status: 503, detail: error });
  }
}

async function runJob<T>(name: string, work: () => Promise<T>, retries = 2): Promise<Result<T>> {
  for (let attempt = 1; attempt <= retries + 1; attempt += 1) {
    try {
      return ok(await work());
    } catch (error) {
      if (attempt <= retries) continue;
      return fail({ kind: "job", code: "JOB_FAILED", message: `${name} failed`, retryable: true, status: 500, detail: { attempt, error } });
    }
  }
  return fail({ kind: "job", code: "JOB_FAILED", message: `${name} failed`, retryable: true, status: 500 });
}

console.log(parseUser({ email: "bad", age: 10 }));
console.log(await callPartner(async () => new Response("down", { status: 503 })));
console.log(await runJob("daily-report", async () => ({ exportedRows: 42 })));

Caso 1: validacion de entrada API

Un fallo de validacion suele ser corregible por el usuario. Email invalido, edad demasiado baja, cuerpo JSON que no es objeto o plan inexistente no deberian verse como una caida del servidor. En el ejemplo, parseUser clasifica el problema como validation, devuelve 400 y marca retryable: false.

Esto mejora la experiencia y la operacion. El frontend puede marcar el campo correcto, el backend puede filtrar logs por EMAIL_INVALID, y Claude Code puede agregar pruebas de fallos concretos. Si quieres convertirlo en una estrategia de pruebas, conecta este patron con API testing con Claude Code y estrategias de testing con Claude Code.

Caso 2: fallos de API externa

Los proveedores externos fallan aunque tu codigo este bien. Pagos, email, CRM, hojas de calculo y analitica pueden devolver timeout, limite de tasa o payload inesperado. El punto importante es separar lo reintentable de lo no reintentable.

En el ejemplo, los 5xx se marcan como retryable: true, mientras que un payload con forma incorrecta se marca como retryable: false. Reintentar una respuesta mal formada solo llena colas y logs. Para confirmar la semantica de respuestas HTTP, usa la referencia oficial de MDN Response.ok. Si usas Express, revisa tambien Express error handling.

Caso 3: fallos de job o batch

Los jobs fallan de forma distinta a una API sincrona. Un reporte nocturno, una importacion CSV o un envio de emails puede fallar cuando nadie esta mirando la pantalla. Por eso runJob conserva nombre del job, numero de intento y si el fallo se puede reintentar. En produccion, esa informacion debe ir a logs estructurados, una cola de fallos, una pantalla interna o una alerta.

La pregunta clave es si se puede ejecutar de nuevo sin causar dano. Si un CSV crea filas duplicadas, el reintento es peligroso. Si un job de facturacion cobra dos veces, el manejo de errores se convierte en incidente. Pide a Claude Code que revise idempotencia y recuperacion, no solo sintaxis.

Errores comunes

El primer error es ocultar el problema con catch { return null; }. Eso elimina la evidencia que Claude Code necesita para depurar. El segundo es devolver detalles internos: stack traces, nombres SQL, variables de entorno o fragmentos de tokens. Para esa parte, revisa auditoria de seguridad con Claude Code. El tercero es reintentar todo. Los fallos de validacion y los payloads imposibles no se corrigen esperando.

Tambien es comun crear tipos bonitos sin una regla de equipo. TypeScript ayuda con uniones discriminadas y narrowing, pero alguien puede volver a throw new Error("failed") manana. Usa la guia oficial de TypeScript Narrowing y escribe la regla en AGENTS.md o CLAUDE.md.

Prompt de revision para Claude Code

Revisa el manejo de errores de este PR.
Comprueba:
1. Los fallos se clasifican en bordes de API, API externa y job/batch.
2. Los fallos que el usuario puede corregir no devuelven 500.
3. retryable y non-retryable estan separados.
4. La respuesta no expone stack traces, SQL, secretos ni rutas internas.
5. Los logs incluyen code, kind, attempt y cause seguro.
6. Hay al menos 3 pruebas de caminos de fallo.
Devuelve el parche minimo y las pruebas necesarias.

Para fijar estos caminos con pruebas puedes usar el Node.js test runner. Para la configuracion de Claude Code y memoria de proyecto, parte de Claude Code overview. Si quieres trabajar primero con pruebas, continua con TDD con Claude Code y tecnicas de debugging.

CTA y resultado probado por Masa

El manejo de errores es un tema ideal para formacion porque conecta API, seguridad, logs, testing y operaciones. Para empezar solo, descarga la chuleta gratuita. Si necesitas prompts, listas de revision y plantillas listas para equipo, mira la biblioteca de productos. Para adaptar un repositorio existente, la pagina de formacion y consultoria de Claude Code permite revisar API, integraciones externas y batches con un caso real.

En el flujo de Masa, mover validacion, APIs externas y batches a una forma parecida a AppError hizo que los prompts fueran mas cortos. Antes escribia “arregla este error”; ahora puede decir “validation devuelve 400, external usa retryable, job conserva attempt”. La revision se concentra en respuesta, log y prueba. No es magia, pero es mucho mas operable que un sistema lleno de 500 anonimos.

#Claude Code #error handling #design patterns #TypeScript #robustness
Gratis

PDF gratis: cheatsheet de Claude Code

Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.

Cuidamos tus datos y no enviamos spam.

Masa

Sobre el autor

Masa

Ingeniero enfocado en workflows prácticos con Claude Code.