Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

244
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda