---
title: "Gestión de errores"
description: "Captura los fallos de la API, actúa según el código de motivo y gestiona las reservas rechazadas."
canonical_url: "https://requiply.com/docs/es/developers/typescript-sdk/error-handling"
---
# Gestión de errores

> Captura los fallos de la API, actúa según el código de motivo y gestiona las reservas rechazadas.

Las respuestas fallidas de la API lanzan `RequiplyError`:

```ts
import { RequiplyError } from '@requiply/api-sdk';

try {
  await requiply.sales.create({ lines: [{ saleItemId, quantity: 1 }], paymentMethod: 'liqpay' });
} catch (error) {
  if (error instanceof RequiplyError && error.reason === 'client_email_required') {
    console.error('LiqPay needs a client with an email');
  } else {
    throw error;
  }
}
```

## Propiedades del error

<table>
<thead>
  <tr>
    <th>
      Propiedad
    </th>
    
    <th>
      Qué contiene
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        status
      </code>
    </td>
    
    <td>
      El estado HTTP de la respuesta, por ejemplo <code>
        400
      </code>
      
      , <code>
        403
      </code>
      
      , <code>
        404
      </code>
      
      , <code>
        409
      </code>
      
       o <code>
        429
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        message
      </code>
    </td>
    
    <td>
      El mensaje legible de la API, con el estado HTTP como alternativa. Muéstraselo a las personas, pero no tomes decisiones según su texto.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        reason
      </code>
    </td>
    
    <td>
      El motivo legible por máquina, cuando la API lo da, por ejemplo <code>
        feature_disabled
      </code>
      
      . Toma las decisiones según este valor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        data
      </code>
    </td>
    
    <td>
      Los campos adicionales que la API envió con el error, incluido <code>
        reason
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        details
      </code>
    </td>
    
    <td>
      El cuerpo de la respuesta ya interpretado, o el texto sin procesar de la respuesta cuando no es JSON.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        retryAfter
      </code>
    </td>
    
    <td>
      Los segundos que hay que esperar, según la cabecera <code>
        Retry-After
      </code>
      
       de un <code>
        429
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

## Motivos de error

`reason` lo devuelven las solicitudes de reserva hechas con claves publicables, los endpoints de [Ventas](https://requiply.com/docs/es/developers/typescript-sdk/sales) y las líneas de venta de los presupuestos y las reservas:

<table>
<thead>
  <tr>
    <th>
      <code>
        reason
      </code>
    </th>
    
    <th>
      Estado
    </th>
    
    <th>
      Significado
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        request_only
      </code>
    </td>
    
    <td>
      <code>
        403
      </code>
    </td>
    
    <td>
      Una clave publicable ha llamado a <code>
        bookings.create()
      </code>
      
       sin <code>
        asRequest: true
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        feature_disabled
      </code>
    </td>
    
    <td>
      <code>
        403
      </code>
    </td>
    
    <td>
      <strong>
        Enable sales
      </strong>
      
       (activar ventas) está desactivado, o la organización no tiene el plan Advanced.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        selling_disabled
      </code>
    </td>
    
    <td>
      <code>
        403
      </code>
    </td>
    
    <td>
      Una clave publicable ha pedido productos en venta cuando la organización no <a href="https://requiply.com/docs/es/developers/typescript-sdk/sales#con-una-clave-publicable">
        vende a los clientes
      </a>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        out_of_stock
      </code>
    </td>
    
    <td>
      <code>
        409
      </code>
    </td>
    
    <td>
      Una clave publicable ha pedido más unidades de las que hay en el almacén. <code>
        data.saleItemId
      </code>
      
       indica el producto y <code>
        data.availableQuantity
      </code>
      
      , cuántas quedan.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invalid_lines
      </code>
    </td>
    
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      Una línea no tiene producto o tiene una cantidad que no es un número entero mayor que cero.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        duplicate_line
      </code>
    </td>
    
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      El mismo producto aparece en dos líneas.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sale_item_not_found
      </code>
    </td>
    
    <td>
      <code>
        404
      </code>
    </td>
    
    <td>
      Un producto no existe en esta organización.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sale_item_archived
      </code>
    </td>
    
    <td>
      <code>
        409
      </code>
    </td>
    
    <td>
      Un producto está archivado y no se puede vender.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        invalid_payment
      </code>
    </td>
    
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      <code>
        paymentMethod
      </code>
      
       no es un método conocido.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        payment_method_unavailable
      </code>
    </td>
    
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      La organización no tiene ninguna integración activa para ese método de pago.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        client_email_required
      </code>
    </td>
    
    <td>
      <code>
        400
      </code>
    </td>
    
    <td>
      LiqPay envía la factura por email, así que la venta necesita un cliente con email.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sale_not_found
      </code>
    </td>
    
    <td>
      <code>
        404
      </code>
    </td>
    
    <td>
      La venta no existe.
    </td>
  </tr>
</tbody>
</table>

Pueden aparecer motivos nuevos, así que mantén siempre una rama alternativa. La mayoría de los demás errores, como un campo que falta o una reserva desconocida, solo llevan `status` y `message`.

## Límites de peticiones

Cada clave puede hacer 100 peticiones por minuto. Las peticiones que superan ese límite lanzan un `RequiplyError` con `status` `429` y `retryAfter` en segundos. En los navegadores falta `retryAfter`, porque la API no expone la cabecera entre orígenes distintos; espera unos segundos antes de reintentar.

## Las reservas rechazadas no son errores

`bookings.create()` no lanza una excepción cuando la organización no puede aceptar una reserva, por ejemplo porque los artículos están ocupados en esas fechas o la recogida queda fuera del horario. Se resuelve con `success: false`, un `message` y, a veces, un `reason`. Consulta [Reservas](https://requiply.com/docs/es/developers/typescript-sdk/bookings#gestionar-la-respuesta).

## Errores que no son `RequiplyError`

La validación del constructor y las API del entorno que faltan lanzan `TypeError`: un `apiKey` que falta o está vacío, que no haya `fetch` disponible, o una clave secreta usada en el navegador. Los fallos de red y las peticiones canceladas se rechazan con el error que lance tu implementación de `fetch`.


## Sitemap

See the full [sitemap](https://requiply.com/docs/sitemap.md) for all pages.
