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

# Manejo de errores

> Java SDK excepciones escritas y estrategia de reintento.

# Manejo de errores

SDK traduce cada código de error HTTP en una subclase anidada de `MarkpdfException` (`RuntimeException`).

```java theme={null}
import tech.markpdf.MarkpdfException;

try {
    ConvertResult result = client.convertFile(Path.of("report.pdf"), ConvertOptions.defaults());
} catch (MarkpdfException e) {
    System.err.printf("Conversion failed (%d): %s%n", e.statusCode(), e.detail());
}
```

## Tabla de excepciones

| Estado HTTP | Clase                                        | causa                                                              |
| ----------: | -------------------------------------------- | ------------------------------------------------------------------ |
|     — (red) | `MarkpdfException.ConnectionException`       | No se pudo conectar, se agotó el tiempo de espera o `IOException`. |
|       `400` | `MarkpdfException.BadRequestException`       | Cuerpo inválido o URL malformado.                                  |
|       `401` | `MarkpdfException.AuthenticationException`   | Falta la clave API o no es válida.                                 |
|       `403` | `MarkpdfException.ForbiddenException`        | Clave sin permiso o host no autorizado de URL.                     |
|       `413` | `MarkpdfException.PayloadTooLargeException`  | Documento, páginas o ZIP fuera de límites.                         |
|       `415` | `MarkpdfException.UnsupportedMediaException` | Formato o `content-encoding` no admitido.                          |
|       `422` | `MarkpdfException.VavalidationException`     | Faltan parámetros requeridos.                                      |
|       `429` | `MarkpdfException.RateLimitException`        | Demasiadas peticiones.                                             |
|       `5xx` | `MarkpdfException.ServerException`           | Error de conversión en el servidor.                                |
| — (trabajo) | `MarkpdfException.JobFailedException`        | El trabajo en cola (`202`) falló después de reintentos internos.   |

Todas extienden `MarkpdfException` y exponente:

```java theme={null}
public class MarkpdfException extends RuntimeException {
    public Integer statusCode();
    public String detail();
    public String requestId();
}
```

\##Capturar excepciones específicas

```java theme={null}
import tech.markpdf.MarkpdfException.*;

try {
    ConvertResult result = client.convertFile(
        Path.of("report.pdf"),
        ConvertOptions.builder().mode(ConvertOptions.Mode.FAST).build()
    );
} catch (AuthenticationException e) {
    throw new RuntimeException("API key invávalida", e);
} catch (PayloadTooLargeException e) {
    System.out.println("Document too large; try pages= to split it.");
} catch (RateLimitException e) {
    System.out.println("Rate limited: " + e.detail());
} catch (VavalidationException e) {
    System.out.println("Parámetros invávavalids: " + e.detail());
} catch (ServerException e) {
    System.out.println("Conversion error; try mode: BALANCED.");
} catch (MarkpdfException e) {
    // catch-all for any other exceptions from SDK
    System.err.println("Error: " + e.detail());
}
```

## Reintentos automáticos

El `HttpClient` interno reintenta automáticamente:

* `429` y `5xx`: reintentos con retroceso exponencial y jitter. Respete `Retry-After` si el servidor lo envía.
* `4xx` diferente de `429`: **no** reintentado.
* Errores de red/tiempo de espera: reintento igual que `5xx`.

<Tip />

## Trabajo falvaválido

```java theme={null}
try {
    ConvertResult result = client.convertFile(Path.of("informe-grande.pdf"), ConvertOptions.defaults());
} catch (MarkpdfException.JobFailedException e) {
    System.out.println("Job " + e.jobId() + " falló: " + e.detail());
}
```

<Warning>
  `JobFailedException` significa que el trabajo ya agotó los reintentos del servidor interno. Volver a intentarlo desde el cliente es razonable, pero hágalo con retroceso.
</Warning>

## Con `CompletableFuture`

Las excepciones lanzadas por métodos asíncronos están incluidas en `CompletionException`; desenvolver con `getCause()`:

```java theme={null}
client.convertBytesAsync(data, "report.pdf", ConvertOptions.defaults())
    .exceptionally(err -> {
        Throwable cause = err.getCause();
        if (cause instanceof MarkpdfException.RateLimitException) {
            System.out.println("Rate limited");
        } else if (cause instanceof MarkpdfException mpe) {
            System.err.println("Error (" + mpe.statusCode() + "): " + mpe.detail());
        }
        return null;
    });
```
