Referencia de Clases de Error del SDK de TypeScript
El paquete @anthropic-ai/sdk lanza una subclase de error distinta para cada estado HTTP que la API de Mensajes puede devolver, para que puedas escribir bloques catch tipados en lugar de analizar códigos de estado manualmente. Esta referencia compara cada clase de error y muestra una cadena de catch funcional, ordenada de más específica a menos específica.
Cómo Usar esta Hoja de Referencia
- Escanea la tabla a continuación para encontrar la clase de error para un estado HTTP o síntoma dado.
- Usa la columna "Reintentable" para decidir si dejar que el reintento incorporado del SDK lo maneje o mostrarlo inmediatamente.
- Copia el ejemplo de cadena
catchy adapta las ramas que realmente necesitas; la mayoría de las aplicaciones no necesitan todas. - Mantén
instanceof Anthropic.APIConnectionErrorordenado antes deinstanceof Anthropic.APIErroren cualquier cadena que escribas, ya que la primera es una subclase de la segunda.
Referencia de Clases de Error
| Clase | Estado HTTP | Reintentable | Causa Típica |
|---|---|---|---|
Anthropic.BadRequestError | 400 | No | Cuerpo de solicitud mal formado, valor de parámetro inválido o una combinación no admitida de opciones. |
Anthropic.AuthenticationError | 401 | No | Clave API faltante, inválida o caducada. |
Anthropic.PermissionDeniedError | 403 | No | La clave API carece de acceso al modelo o recurso solicitado. |
Anthropic.NotFoundError | 404 | No | El recurso referenciado (ej. un ID de modelo o archivo) no existe. |
Anthropic.UnprocessableEntityError | 422 | No | La solicitud es JSON bien formado pero falla la validación semántica. |
Anthropic.RateLimitError | 429 | Sí | Demasiadas solicitudes o tokens para el nivel de límite de tasa actual. |
Anthropic.InternalServerError | >=500 | Sí | Fallo transitorio del lado de Anthropic. |
Anthropic.APIConnectionError | (ninguno, no se recibió respuesta) | Sí | Fallo de red, error de DNS o tiempo de espera agotado antes de que llegue una respuesta. |
Anthropic.APIError | (clase base) | Depende | Padre comodín; coincide solo si ninguna subclase más específica coincidió primero. |
Nota sobre la Jerarquía de Clases
Anthropic.APIConnectionError es una subclase de Anthropic.APIError en el SDK de TypeScript, a diferencia de Python, donde APIConnectionError es una clase hermana. Esto significa que una verificación instanceof Anthropic.APIError también coincidirá con un error de conexión. Siempre verifica APIConnectionError (y cualquier otra subclase específica) antes de la verificación genérica APIError en una cadena if/else if, o la rama específica nunca se ejecutará.
Cadena catch de Más Específica a Menos Específica
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
async function askClaude(prompt: string) {
try {
return await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: prompt }],
});
} catch (error) {
if (error instanceof Anthropic.RateLimitError) {
// Reintentable: el SDK ya reintentó internamente (maxRetries por defecto: 2).
// Si aún falló, espera más o pon en cola la solicitud.
console.error(`Límite de tasa alcanzado (tipo: ${error.type}). Inténtalo de nuevo más tarde.`);
} else if (error instanceof Anthropic.AuthenticationError) {
// No reintentable: corrige la clave API, no reintentes.
console.error(`Fallo de autenticación (tipo: ${error.type}). Verifica ANTHROPIC_API_KEY.`);
} else if (error instanceof Anthropic.BadRequestError) {
// No reintentable: corrige la carga útil de la solicitud.
console.error(`Solicitud incorrecta (tipo: ${error.type}): ${error.message}`);
} else if (error instanceof Anthropic.InternalServerError) {
// Reintentable: fallo transitorio del lado del servidor.
console.error(`Error del servidor (tipo: ${error.type}). Seguro para reintentar.`);
} else if (error instanceof Anthropic.APIConnectionError) {
// Reintentable: verifica esto ANTES de la verificación base de APIError a continuación,
// ya que APIConnectionError es una subclase de APIError.
console.error("Error de red, no se recibió ninguna respuesta.");
} else if (error instanceof Anthropic.APIError) {
// Captura para cualquier otro error API tipado (estado, tipo disponibles).
console.error(`Error API ${error.status} (tipo: ${error.type}): ${error.message}`);
} else {
// No es un error del SDK en absoluto (un error en el código que llama, por ejemplo).
throw error;
}
}
}Reintentable vs No Reintentable de un Vistazo
| Categoría | Clases | Manejo Recomendado |
|---|---|---|
| Reintentable | RateLimitError, InternalServerError, APIConnectionError | Deja que el backoff exponencial incorporado del SDK lo maneje (por defecto maxRetries: 2); registra y muestra solo si aún falla después de los reintentos. |
| No Reintentable | BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, UnprocessableEntityError | Falla rápido, muestra el .message y .type al llamador, y corrige la solicitud o las credenciales en lugar de reintentar. |
La Propiedad .type
Cada error del SDK también expone una propiedad .type con la cadena de tipo de error de la API, que proporciona una clasificación más detallada que solo el código de estado HTTP. Dos errores pueden compartir un estado pero tener un .type diferente:
try {
await client.messages.create({ /* ... */ });
} catch (error) {
if (error instanceof Anthropic.APIError) {
switch (error.type) {
case "invalid_request_error":
// se mapea a BadRequestError (400)
break;
case "authentication_error":
// se mapea a AuthenticationError (401)
break;
case "rate_limit_error":
// se mapea a RateLimitError (429)
break;
case "overloaded_error":
// puede llegar como un 429 o 5xx dependiendo de la causa
break;
}
}
}Preguntas Frecuentes
¿Por qué APIConnectionError necesita ser verificado antes que APIError?
Porque en el SDK de TypeScript, APIConnectionError es una subclase de APIError, no una hermana. Una verificación instanceof Anthropic.APIError también coincide con errores de conexión, por lo que si esa verificación viene primero en una cadena if/else if, la rama más específica APIConnectionError nunca se ejecuta.
¿Es esta la misma jerarquía que el SDK de Python?
No. En el SDK de Python, APIConnectionError es una hermana de APIError, no una subclase. El código portado de Python a TypeScript que asume la misma relación omitirá silenciosamente la rama de error de conexión.
¿Necesito reintentar manualmente RateLimitError o InternalServerError?
No usualmente. El SDK ya reintenta automáticamente errores 429, 5xx y de conexión con backoff exponencial, usando un maxRetries predeterminado de 2. Solo agrega tu propia lógica de reintento si necesitas un número de reintentos diferente, una estrategia de backoff o un comportamiento de cola.
¿Qué errores nunca deben reintentarse?
BadRequestError (400), AuthenticationError (401), PermissionDeniedError (403), NotFoundError (404) y UnprocessableEntityError (422). Reintentar estos desperdicia una solicitud ya que la carga útil o las credenciales, no la red o la carga del servidor, causaron el fallo.
¿Qué captura la clase base APIError?
Cualquier error tipado del SDK que no coincidió con un instanceof más específico anteriormente en la cadena, ya que cada clase de error específica extiende APIError. Colócala al final de una cadena catch como una red de seguridad, no como tu ruta de manejo principal.
¿Cómo se diferencia `.type` de `.status`?
.status es el código de estado HTTP (un número, como 429). .type es la cadena de tipo de error propia de la API (como "rate_limit_error" o "overloaded_error"), que te permite distinguir causas que comparten el mismo código de estado.
¿Puede `overloaded_error` aparecer con un estado distinto de 429?
Sí, overloaded_error puede llegar bajo un estado 429 o 5xx dependiendo de la causa, que es exactamente el caso en el que verificar .type además de la clase mapeada por estado te da información más precisa.
¿Qué activa específicamente APIConnectionError?
Cualquier cosa que impida que llegue una respuesta, como un fallo de DNS, una conexión caída o un tiempo de espera agotado del lado del cliente. Es distinto de los errores de código de estado porque nunca se recibió una respuesta HTTP.
¿Debo capturar errores por llamada o con un wrapper compartido?
Para una aplicación pequeña, una función wrapper compartida (como askClaude arriba) que centraliza la cadena catch mantiene el manejo consistente. Para aplicaciones más grandes, envuelve la cadena catch en una utilidad para que cada sitio de llamada obtenga la misma clasificación de reintentable/no reintentable sin duplicar la cadena if/else if.
¿Importa volver a lanzar el error en la rama else final?
Sí. El else final en el ejemplo vuelve a lanzar cualquier cosa que no sea un APIError del SDK en absoluto, como un error en tu propio código de llamada. Ignorar silenciosamente errores que no son del SDK hace que los errores reales sean más difíciles de encontrar.
¿Es UnprocessableEntityError común en la práctica?
Menos común que BadRequestError, ya que significa que la solicitud era JSON sintácticamente válido pero falló una verificación semántica, como un valor que es del tipo correcto pero fuera de un rango permitido.
¿Qué nombre de modelo debo usar en el código de ejemplo?
El ejemplo usa claude-sonnet-5, el modelo predeterminado en la línea actual de Claude (Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5, Claude Haiku 4.5). Reemplázalo con el modelo que tu aplicación tenga como objetivo.
Relacionado
- Conceptos Básicos del SDK de TypeScript/JavaScript - instala el SDK y haz tu primera llamada tipada antes de manejar errores.
- Patrones de Reintento, Tiempo de Espera y AbortController en el SDK de TypeScript - ajusta el reintento incorporado del SDK y el comportamiento de cancelación referenciados en esta página.
- El Modelo Mental del SDK de TypeScript de Anthropic - cómo el cliente del SDK, las solicitudes y las respuestas tipadas encajan.
Versiones de Stack: Escrito contra la línea de modelos Claude actual a partir de ~junio de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (el predeterminado), y Claude Haiku 4.5 - y el SDK oficial de TypeScript
@anthropic-ai/sdk(última versión). Los nombres de modelos, versiones de SDK y precios cambian rápidamente; verifica los detalles actuales en platform.claude.com/docs antes de confiar en ellos.