Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

241
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda