Cliente API

Errores y Límites de Tasa

Maneja errores de API y límites de tasa usando las clases de error tipadas y la lógica de reintentos integrada de WhataloClient.

WhataloClient lanza clases de error tipadas para cada respuesta que no sea 2xx. Capturar tipos de error específicos te permite manejar fallos con precisión y mostrar mensajes significativos a los comerciantes.

Jerarquía de Clases de Error

Todos los errores extienden WhataloAPIError, que proporciona los campos comunes compartidos entre todos los tipos de error.

import {
  WhataloAPIError,
  AuthenticationError,
  AuthorizationError,
  NotFoundError,
  ValidationError,
  RateLimitError,
  InternalError,
} from "@whatalo/plugin-sdk";

Campos Comunes (WhataloAPIError)

CampoTipoDescripción
statusCodenumberCódigo de estado HTTP de la respuesta
codestringCódigo de error legible por máquina
requestIdstring | undefinedID único de solicitud para escalación de soporte
messagestringDescripción legible por humanos

Referencia de Clases de Error

ClaseEstado HTTPCódigoCampos extra
AuthenticationError401authentication_error
AuthorizationError403authorization_errorrequiredScope: string
NotFoundError404not_foundresourceType: string, resourceId: string
ValidationError422validation_errorfieldErrors: { field, message }[]
RateLimitError429rate_limit_exceededretryAfter: number (segundos)
InternalError500internal_error

Ejemplos de Manejo de Errores

Patrón básico

import {
  WhataloClient,
  NotFoundError,
  RateLimitError,
  ValidationError,
  AuthorizationError,
  AuthenticationError,
} from "@whatalo/plugin-sdk";

const client = new WhataloClient({ apiKey: process.env.WHATALO_API_KEY! });

try {
  const product = await client.products.get("999999999999");
} catch (error) {
  if (error instanceof NotFoundError) {
    // Product does not exist
    console.log(`${error.resourceType} not found: ${error.resourceId}`);
  } else if (error instanceof AuthorizationError) {
    // Plugin is missing the required scope
    console.log(`Insufficient permissions. Required: ${error.requiredScope}`);
  } else if (error instanceof AuthenticationError) {
    // API key is invalid or has been revoked
    console.log("Invalid API key — check your WHATALO_API_KEY");
  } else if (error instanceof RateLimitError) {
    // Too many requests — wait before retrying
    console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
  } else if (error instanceof ValidationError) {
    // Request body failed validation
    error.fieldErrors.forEach((e) => {
      console.log(`  ${e.field}: ${e.message}`);
    });
  } else {
    // Unknown error — re-throw so it surfaces properly
    throw error;
  }
}

Manejo de errores de validación en create/update

import { ValidationError } from "@whatalo/plugin-sdk";

try {
  await client.products.create({
    name: "", // Empty name is invalid
    price: -5, // Negative price is invalid
  });
} catch (error) {
  if (error instanceof ValidationError) {
    const messages = error.fieldErrors
      .map((e) => `${e.field}: ${e.message}`)
      .join("\n");

    throw new Error(`Product creation failed:\n${messages}`);
  }
  throw error;
}

Límites de Tasa

Leer el estado del límite de tasa

Después de cada llamada a la API, el cliente actualiza su propiedad rateLimit leyendo los encabezados de la respuesta:

await client.products.list({ page: 1, per_page: 10 });

console.log(client.rateLimit);
// { limit: 100, remaining: 89, reset: 1709280000 }
CampoEncabezado fuenteDescripción
limitX-RateLimit-LimitMáximo de solicitudes por ventana
remainingX-RateLimit-RemainingSolicitudes restantes en la ventana actual
resetX-RateLimit-ResetMarca de tiempo Unix cuando se restablece la ventana

Verificaciones proactivas de límite de tasa

Para operaciones por lotes, verifica client.rateLimit.remaining antes de cada llamada:

const productIds = ["472819365001", "472819365002", "472819365003", /* ... */];

for (const id of productIds) {
  // Pause if fewer than 10 requests remain to avoid hitting the limit
  if (client.rateLimit.remaining < 10) {
    const msUntilReset = client.rateLimit.reset * 1000 - Date.now();
    await new Promise((resolve) => setTimeout(resolve, msUntilReset + 100));
  }

  await client.products.get(id);
}

Reintentos Automáticos

Configura retries en el cliente para reintentar automáticamente errores 5xx con backoff exponencial:

const client = new WhataloClient({
  apiKey: process.env.WHATALO_API_KEY!,
  retries: 3, // Retry up to 3 times on server errors
});
IntentoRetraso
1er reintento1 segundo
2do reintento2 segundos
3er reintento4 segundos

RateLimitError (429) no se reintenta automáticamente. Usa error.retryAfter para programar tu propio reintento:

import { RateLimitError } from "@whatalo/plugin-sdk";

async function withRateLimitRetry<T>(fn: () => Promise<T>): Promise<T> {
  try {
    return await fn();
  } catch (error) {
    if (error instanceof RateLimitError) {
      await new Promise((resolve) =>
        setTimeout(resolve, error.retryAfter * 1000)
      );
      return fn(); // Single retry after the window resets
    }
    throw error;
  }
}

const product = await withRateLimitRetry(() =>
  client.products.get("472819365047")
);

Registro de IDs de Solicitud

Incluye requestId en los logs de error para facilitar la escalación de soporte:

import { WhataloAPIError } from "@whatalo/plugin-sdk";

try {
  await client.orders.get("order_123");
} catch (error) {
  if (error instanceof WhataloAPIError) {
    console.error({
      message: error.message,
      code: error.code,
      statusCode: error.statusCode,
      requestId: error.requestId, // Include in support tickets
    });
  }
  throw error;
}

On this page