> ## Documentation Index
> Fetch the complete documentation index at: https://commet.co/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Manejo de errores

> Maneja errores con reintentos automáticos y clases de error tipadas

## Clases de error

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { CommetAPIError, CommetValidationError } from '@commet/node'

    try {
      await commet.customers.create({ email: 'invalid' })
    } catch (error) {
      if (error instanceof CommetValidationError) {
        console.log(error.validationErrors)
        // { email: ['Invalid email format'] }
      }

      if (error instanceof CommetAPIError) {
        console.log(error.statusCode, error.message)
      }
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from commet import CommetAPIError, CommetValidationError

    try:
        commet.customers.create(email='invalid')
    except CommetValidationError as e:
        print(e.validation_errors)
        # { 'email': ['Invalid email format'] }
    except CommetAPIError as e:
        print(e.status_code, e)
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    import (
        "errors"

        "github.com/commet-labs/commet-go/v9"
    )

    _, err := client.Customers.Create(ctx, &commet.CreateCustomerParams{Email: "invalid"})
    if err != nil {
        var validationErr *commet.ValidationError
        if errors.As(err, &validationErr) {
            fmt.Println(validationErr.ValidationErrors)
            // map[email:[Invalid email format]]
        }

        var apiErr *commet.CommetError
        if errors.As(err, &apiErr) {
            fmt.Println(apiErr.StatusCode, apiErr.Message)
        }
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    import co.commet.CommetApiException;
    import co.commet.CommetValidationException;
    import co.commet.params.CreateCustomerParams;

    try {
        commet.customers().create(CreateCustomerParams.builder("invalid").build());
    } catch (CommetValidationException e) {
        System.out.println(e.getValidationErrors());
        // { email: [Invalid email format] }
    } catch (CommetApiException e) {
        System.out.println(e.getStatusCode() + " " + e.getMessage());
    }
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    use Commet\Exceptions\ApiException;
    use Commet\Exceptions\ValidationException;

    try {
        $commet->customers->create(email: 'invalid');
    } catch (ValidationException $e) {
        print_r($e->validationErrors);
        // [ 'email' => ['Invalid email format'] ]
    } catch (ApiException $e) {
        echo $e->getStatusCode() . ' ' . $e->getMessage();
    }
    ```
  </Tab>
</Tabs>

| Clase | Caso de uso |
| - | - |
| `CommetAPIError` / `CommetApiException` / `ApiException` | Errores HTTP (4xx, 5xx) |
| `CommetValidationError` / `CommetValidationException` / `ValidationException` | Input inválido con detalles por campo |
| `CommetError` / `CommetException` | Clase base de todos los errores |

Go expone `*commet.CommetError` y `*commet.ValidationError` como tipos concretos — verifícalos con `errors.As`.

## Referencia de códigos de error

Cada error actual de la API incluye un `code` estable y un `doc_url` correspondiente a la versión resuelta, como [`customer_not_found`](/docs/api-reference/errors/customer_not_found.md). La URL devuelve una referencia Markdown dedicada en inglés con instrucciones de manejo y reintento para esa versión de la API.

Conservá el header `x-request-id` de la respuesta al registrar o reportar un error. Commet registra el mismo identificador en Platform, lo que permite correlacionar el request sin incluir credenciales ni datos del customer.

## Reintentos automáticos

Los requests fallidos se reintentan con backoff exponencial (1s → 2s → 4s, máx 8s).

**Reintentables:** 408, 429, 500, 502, 503, 504

Los rate limits son la excepción al backoff: un 429 se reintenta solo cuando el response trae el header `Retry-After`, y el cliente espera exactamente ese valor (con tope de 30s) en lugar del backoff. Un 429 sin `Retry-After` no se reintenta.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const commet = new Commet({
      apiKey: process.env.COMMET_API_KEY!,
      retries: 3,  // default
    })
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    commet = Commet(
        api_key=os.environ['COMMET_API_KEY'],
        retries=3,  # default
    )
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    client, err := commet.New(
        os.Getenv("COMMET_API_KEY"),
        commet.WithRetries(3), // default
    )
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    Commet commet = Commet.builder()
        .apiKey(System.getenv("COMMET_API_KEY"))
        .retries(3) // default
        .build();
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    $commet = new Commet(
        apiKey: getenv('COMMET_API_KEY'),
        retries: 3, // default
    );
    ```
  </Tab>
</Tabs>

## Uso no bloqueante

No dejes que los errores de tracking rompan tu app:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    commet.usage.track({
      customerId: 'user_123',
      featureCode: 'api_calls',
    }).catch(console.error)

    // Continúa sin esperar
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    try:
        commet.usage.track(customer_id='user_123', feature_code='api_calls')
    except Exception as e:
        logger.error(e)

    # Continúa sin esperar
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    go func() {
        _, err := client.Usage.Track(context.Background(), &commet.TrackUsageParams{
            CustomerID: "user_123",
            FeatureCode: "api_calls",
        })
        if err != nil {
            log.Printf("track failed: %v", err)
        }
    }()

    // Continúa sin esperar
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    CompletableFuture.runAsync(() -> {
        try {
            commet.usage().track(
                TrackUsageParams.builder("api_calls", "user_123")
                    .customerId("user_123")
                    .build()
            );
        } catch (Exception e) {
            log.error("track failed", e);
        }
    });

    // Continúa sin esperar
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    try {
        $commet->usage->track(
            customerId: 'user_123',
            featureCode: 'api_calls',
        );
    } catch (\Throwable $e) {
        error_log($e->getMessage());
    }

    // Continúa sin esperar
    ```
  </Tab>
</Tabs>


## Related topics

- [Introducción](/docs/es/index.md)
- [Testing](/docs/es/testing-sandbox.md)
- [Manejar pagos fallidos](/docs/es/handle-failed-payments.md)
- [Skills de Commet](/docs/es/commet-skill.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.