Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

239
Views
Prueba/atrapa la función asíncrona fuera del contexto asíncrono

Tengo algunas clases que usan 'dns' de node.js. Pero cuando ocurre un error, mi aplicación se lanza. Hice un ejemplo simple con clases y funciones lanzables y me enfrenté al mismo problema. Funciona si se lanza una excepción desde la función, pero no funciona si se lanza una excepción desde la clase. Ejemplo:

 class Test { constructor() { this.t(); } async t() { throw new Error("From class"); } } async function test(){ new Test(); } try { test().catch(e => { console.log("From async catch"); }); } catch (e) { console.log("From try catch"); }

Producción:

 Uncaught (in promise) Error: From class at Test.t (<anonymous>:6:11) at new Test (<anonymous>:3:10) at test (<anonymous>:11:3) at <anonymous>:15:3

¿Cómo detectar errores del bloque try/catch en este ejemplo?

UPD: Código completo (mecanografiado):

 export class RedisService { client: any; expirationTime: any; constructor(args: RedisServiceOptions) { let redisData: any = {}; if (args.password) redisData["defaults"] = { password: args.password }; dns.resolveSrv(args.host, (err, addresses) => { if (err) { /// Handling error in main func } else { log.info("Using Redis cluster mode"); redisData["rootNodes"] = addresses.map(address => { log.info(`Adding Redis cluster node: ${address.name}:${address.port}`); return Object({ url: `redis://${address.name}:${address.port}` }) }); this.client = createCluster(redisData); }; this.client.on('error', (err: Error) => log.error(`Redis error: ${err.message}`)); this.client.connect().then(() => { log.info("Connected to Redis") }); }); this.expirationTime = args.expirationTime; } /// Class functions }
about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Generas múltiples solicitudes asíncronas pero solo puedes detectar errores desde la primera:

  1. Creas una promesa con async function test() .

  2. Luego, crea una llamada sincrónica dentro de él, con new Test() , cada error lanzado sincrónicamente desde dentro será capturado por catch .

  3. Luego genera otra llamada de promesa desde dentro del constructor síncrono, este error no puede ser detectado por el bloque try/catch o .catch en o por encima de la async function test() .

    Es similar a esto:

     constructor() { new Promise(() => throw new Error('')) }

Así que tienes 3 formas posibles de resolverlo:

  1. Captas el error dentro de la async t() {} .
  2. Lo atrapa dentro del constructor con this.t().catch(console.error) (que no se puede reenviar al bloque try/catch) ya que se reenvía al bloque catch de la Promesa detrás de la llamada asíncrona. Y si no hay .catch en la llamada asíncrona, obtiene el error "Rechazo de promesa no controlada".
  3. No llames a la función asíncrona desde dentro del constructor, úsala así:
     class Test { async t() { throw new Error("From class"); } } async function test(){ await (new Test()).t(); } try { test().catch(e => { console.log("From async catch"); }); } catch (e) { console.log("From try catch"); }
about 4 years ago · Juan Pablo Isaza Report

0

No hagas métodos asíncronos)))

Su solución se parece un poco a esto.

 class Test { constructor() { this.t(); } t() { (async () => { try { throw new Error("From class"); } catch (e) { console.log(e); } })(); } }

Que tengas un buen resto de tu día.

about 4 years ago · Juan Pablo Isaza Report

0

no funciona si se lanza una excepción desde la clase.

En particular, cuando ocurre un evento de error asíncrono en el constructor , sí. Como dice el título de su pregunta, no puede manejar errores fuera de un contexto async , y un constructor no es eso.

Su implementación actual tiene muchos problemas, desde que client no está undefined hasta que se inicializa hasta no poder notificar a la persona que llama sobre los errores.

Todo esto se puede solucionar no poniendo código de inicialización asincrónica dentro de un constructor . Cree la instancia solo una vez que tenga todas las partes, use una función de fábrica auxiliar async para obtener (y esperar) las partes.

 export class RedisService { client: RedisClient; expirationTime: number | null; constructor(client: RedisClient, expirationTime: number | null) { this.client = client; this.expirationTime = expirationTime; } static create(args: RedisServiceOptions) { const addresses = await dns.promises.resolveSrv(args.host); log.info("Using Redis cluster mode"); const redisData = { defaults: args.password ? { password: args.password } : undefined, rootNodes: addresses.map(address => { log.info(`Adding Redis cluster node: ${address.name}:${address.port}`); return { url: `redis://${address.name}:${address.port}` }; }), }; const client = createCluster(redisData); client.on('error', (err: Error) => log.error(`Redis error: ${err.message}`)); await this.client.connect(); log.info("Connected to Redis"); return new RedisService(client, args.expirationTime); } … // instance methods }

Ahora, en su función principal, puede llamar a create , usar await y manejar los errores:

 async function main(){ try { const service = await RedisService.create(…); } catch(e) { console.log("From async catch", e); } }
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!