> ## 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.

# Error handling

> @markpdf/react-native typed exceptions and retry patterns on mobile.

# Error handling

The client translates each HTTP error code into a subclass of `MarkpdfError`:

```ts theme={null}
import { MarkpdfError } from "@markpdf/react-native";

try {
  const markdown = await client.convertLocalFile({ uri, name });
} catch (err) {
  if (err instanceof MarkpdfError) {
    console.error(`Failed (${err.statusCode}): ${err.message}`);
  } else {
    throw err;
  }
}
```

## Error table

| Status HTTP | Clase                      | Causa                                               |
| ----------: | -------------------------- | --------------------------------------------------- |
|       `400` | `BadRequestError`          | Invavalid or URL malformed body.                    |
|       `401` | `AuthenticationError`      | API key missing or invavalid.                       |
|       `403` | `ForbiddenError`           | Key without permission or unauthorized host of URL. |
|       `413` | `PayloadTooLargeError`     | Document, pages or ZIP out of bounds.               |
|       `415` | `UnsupportedFormatError`   | Format or `content-encoding` not supported.         |
|       `422` | `UnprocessableEntityError` | Required parameters are missing.                    |
|       `429` | `RateLimitError`           | Demasiadas peticiones.                              |
|       `500` | `ConversionError`          | Conversion error on the server.                     |
|     — (job) | `JobFailedError`           | The queued job (`202`) failed.                      |

Todas exponen:

```ts theme={null}
class MarkpdfError extends Error {
  statusCode?: number;
  detail?: unknown;
}
```

## Capture specific errors

```ts theme={null}
import {
  AuthenticationError,
  PayloadTooLargeError,
  RateLimitError,
  UnprocessableEntityError,
  ConversionError,
} from "@markpdf/react-native";

try {
  const markdown = await client.convertLocalFile({ uri, name }, { mode: "fast" });
} catch (err) {
  if (err instanceof AuthenticationError) {
    Alert.alert("API key invávalida");
  } else if (err instanceof PayloadTooLargeError) {
    Alert.alert("Document too large. Try pages= to split it.");
  } else if (err instanceof RateLimitError) {
    Alert.alert("Demasiadas peticiones. Intenta de nuevo en unos segundos.");
  } else if (err instanceof UnprocessableEntityError) {
    Alert.alert("Parámetros invávavalids.");
  } else if (err instanceof ConversionError) {
    Alert.alert("Conversion error. Try mode: 'balanced'.");
  } else {
    throw err;
  }
}
```

## Reintentos

`@markpdf/react-native` **does not** implement automatic retries — unlike Node.js's SDK, there is no `maxRetries` in the constructor. Implement your own backoff if you need it, especially relevant on mobile where the network is intermittent:

```ts theme={null}
async function convertWithRetry(file: LocalFile, attempts = 3): Promise<ConvertResult> {
  for (let i = 0; i < attempts; i++) {
    try {
      return await client.convertLocalFile(file, { mode: "fast" });
    } catch (err) {
      const retryable = err instanceof RateLimitError || err instanceof ConversionError || !(err instanceof MarkpdfError);
      if (!retryable || i === attempts - 1) throw err;
      await new Promise((r) => setTimeout(r, 2 ** i * 1000));
    }
  }
  throw new Error("unreachable");
}
```

<Tip>
  Errors without `MarkpdfError` (network drop, `AbortError`) are also candidates for retry — they are common on mobile when switching from WiFi to mobile data mid-upload.
</Tip>

## Job falvavalid

```ts theme={null}
import { JobFailedError } from "@markpdf/react-native";

try {
  const markdown = await client.convertLocalFile({ uri, name: "informe-grande.pdf" });
} catch (err) {
  if (err instanceof JobFailedError) {
    console.error(`Job falló: ${err.message}`);
  } else {
    throw err;
  }
}
```
