Objetivo técnico
Al terminar podrás esperar una operación externa, capturar su fallo y conservar la causa sin exponerla al usuario. Un RAG encadena base de datos, embeddings y modelo; cualquiera puede fallar de forma independiente.
Antes de empezar
Necesitas ejecutar TypeScript con tsx. Crea src/async.ts. Trabajaremos con una promesa simulada para practicar sin gastar tokens.
Paso a paso
- Crea una función que simula retrieval:
async function retrieve(shouldFail: boolean): Promise<string[]> {
await new Promise((resolve) => setTimeout(resolve, 50));
if (shouldFail) throw new Error('database unavailable');
return ['chunk-1', 'chunk-2'];
}
async function run() {
try {
const chunks = await retrieve(false);
console.log({ ok: true, chunks });
} catch (error) {
console.error({ event: 'retrieval_failed', error });
console.log({ ok: false, code: 'RETRIEVAL_ERROR' });
}
}
run();
- Ejecuta
npx tsx src/async.ts. - Cambia
retrieve(false)porretrieve(true). - Observa dos audiencias: el log técnico conserva la causa; la respuesta pública usa un código estable.
- Quita
awaittemporalmente. Verás que obtienes una promesa, no los chunks resueltos.
Verificación
Ejecuta éxito y fallo. Ninguno debe dejar un rechazo sin manejar. El fallo debe producir RETRIEVAL_ERROR, no una respuesta inventada ni un 200 exitoso.
Errores frecuentes
- Olvidar
awaity tratar una promesa como un array. - Capturar el error y continuar como si hubiera contexto.
- Devolver el mensaje interno de la base de datos al cliente.
Práctica
Agrega un tercer modo que devuelva []. Diferéncialo del fallo: “sin resultados” es un resultado válido; “base caída” es un error operativo. Escribe la salida esperada antes de ejecutarlo.
Puente al RAG
En Bloque 5 debes distinguir no-contexto, proveedor caído y respuesta correcta. Esa separación permite evaluar el sistema sin confundir calidad con disponibilidad.