> ## Documentation Index
> Fetch the complete documentation index at: https://acme-c84a37e5.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling

> Normalización de errores a ResultError y reglas personalizables

## AppResultErrorError

La librería normaliza valores desconocidos a un `ResultError` con:

* `code`: identificador estable
* `message`: descripción del error
* `status?`: estado numérico opcional
* `meta?`: payload adicional
* `cause?`: valor original

## Normalizador por defecto

Si no configuras reglas personalizadas, `tryo` aplica automáticamente las siguientes reglas:

* **abort**: Detecta `AbortError` y devuelve `code: "ABORTED"`.
* **timeout**: Detecta `TimeoutError` y devuelve `code: "TIMEOUT"`.
* **httpStatus**: Detecta errores con `status` o `statusCode` numérico. Devuelve `code: "HTTP"` y preserva el status.
* **aggregate**: Maneja `AggregateError` guardando los errores internos en `meta.errors`.
* **string**: Si se lanza un string, se usa como mensaje.
* **message**: Extrae la propiedad `message` de objetos.

Ejemplo de uso de reglas por defecto:

```typescript theme={null}
import tryo from "tryo";

const runner = tryo(); // Usa reglas por defecto

const result = await runner.run(async () => {
  throw new DOMException("Time out", "TimeoutError");
});

if (!result.ok && result.error.code === "TIMEOUT") {
  console.log("La petición excedió el tiempo límite");
}
```

## Reglas personalizadas

Usa `errorRule` para definir mapeos específicos y `tryo` para aplicarlos.

```typescript theme={null}
import tryo, { errorRule } from "tryo";

class HttpError extends Error {
  constructor(
    public status: number,
    public url: string,
    public body?: unknown
  ) {
    super("HTTP error");
  }
}

const runner = tryo({
  rules: [
    errorRule.instance(HttpError).toError((e) => ({
      code: "HTTP",
      message: `Request failed (${e.status})`,
      status: e.status,
      meta: { url: e.url, body: e.body },
      cause: e,
    })),
  ],
});
```

## Transformación con `mapError`

Permite ajustar el error ya normalizado para enriquecerlo o estandarizarlo.

```typescript theme={null}
const r = await run(() => fetch("/api"), {
  mapError: (e) => ({ ...e, message: `[api] ${e.message}` }),
});
```

## Cancelación y Timeout

* `signal` y `timeout` controlan cuánto tiempo esperamos el resultado.
* Si tu función no usa el `AbortSignal` provisto, la librería no puede cancelar el I/O subyacente de forma mágica.
* Se hace un `race` y se devuelve `ABORTED`/`TIMEOUT` rápido, pero la petición interna solo se detiene si coopera con el `signal`.

```typescript theme={null}
const controller = new AbortController();
const r = await run(() => fetch("/api"), { signal: controller.signal, timeout: 2000 });
```

## Circuit Breaker (a nivel Runner)

* Se configura a nivel Runner: `tryo({ circuitBreaker })`.
* No se expone por llamada en `RunOptions` para mantener la API simple.
