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

141
Visualizações
Catch block does not execute immediately after exception is thrown in try block

I have a bit of Javascript code, which is not behaving as I'd expect it to. Can someone tell me what is going on here?

Here's a simplified version:

    let recordsProcessed = 0
    await parser(fileBuffer,

      // Process row
      async (row: Record<string, any>) => {
        recordsProcessed += 1
        try {
          console.log('Processing record', recordsProcessed)
          await processRow(row)
        } catch (e) {
          console.log('Failure at record', recordsProcessed)
        }
      }
    ) 

    async parser(fileBuffer: Buffer, rowCb: Function, ...) : Promise<number> {
      ... 
      return new Promise((resolve, reject) => {
        parseFile(fileBuffer, options)
          .on('error', (error:any) => reject(error))
          .on('data', async row => await rowCb(row))
          .on('end', (count: any) => resolve(count))
      })
      ...
    }

The parser() here is an async function, but it also calls some callbacks passed to it (I'm only showing one here, but there are multiple). It calls the rowCb() callback for each row in a file.

It's the try/catch block within the async callback which is not behaving as I'd expect. I'm using a test file, with three rows, which will cause every call to processRow() to throw an exception. So, I'd expect the output from the console.logs to be:

Processing record 1
Failure at record 1
Processing record 2
Failure at record 2
Processing record 3
Failure at record 3

But instead I'm getting this:

Processing record 1
Processing record 2
Processing record 3
Failure at record 3
Failure at record 3
Failure at record 3

Why is this happening? Since I'm awaiting processRow(), shouldn't it be in the same scope as the try/catch block, and therefore the catch() should be processed immediately after the processRow() throws an exception?

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

If it's processing multiple lines, parseFile() must have some loop inside. It's unclear if it's your code or it's coming from some library, but that loop either expects to work with asynchronous callbacks, or it doesn't. Perhaps those unshown options also affect this.

If it used a loop with await, the output would be what you expect:

async function thrower(i) {
  throw "throwing " + i;
}

let somevariable = 0;
async function wrapper(i) {
  try {
    somevariable++;
    console.log("calling", i, "(" + somevariable + ")");
    await thrower(i);
  } catch (x) {
    console.log("caught", x, "(" + somevariable + ")");
  }
}

(async function() {
  for await (let i of [1, 2, 3])     // <-- async-aware loop
    wrapper(i);
})()

However if it doesn't use await, then the loop progresses immediately when wrapper() encounters its own await line:

async function thrower(i) {
  throw "throwing " + i;
}

let somevariable = 0;
async function wrapper(i) {
  try {
    somevariable++;
    console.log("calling", i, "(" + somevariable + ")");
    await thrower(i);
  } catch (x) {
    console.log("caught", x, "(" + somevariable + ")");
  }
}

(async function() {
  for (let i of [1, 2, 3])           // <-- async-unaware loop
    wrapper(i);
})()

And if it's an ancient forEach(), then it doesn't matter even if it tries to await:

async function thrower(i) {
  throw "throwing " + i;
}

let somevariable = 0;
async function wrapper(i) {
  try {
    somevariable++;
    console.log("calling", i, "(" + somevariable + ")");
    await thrower(i);
  } catch (x) {
    console.log("caught", x, "(" + somevariable + ")");
  }
}

(async function() {
  //[1, 2, 3].forEach(wrapper); // <- would be enough to produce the same output
  [1, 2, 3].forEach(async function(i){
    await wrapper(i);           // <- absolutely futile attempt to wait,
                                //    forEach just can't work asynchronously
  });
})()

about 4 years ago · Juan Pablo Isaza Relatório

0

You need to add a new variable inside of the parser to get the number of the current record. You should use that variable instead of the global one.

let recordsProcessed = 0
await parser(fileBuffer,
  // Process row
  async (row: Record<string, any>) => {
    recordsProcessed += 1
    let thisRecordNum = recordsProcessed;
    try {
      console.log('Processing record', thisRecordNum)
      await processRow(row)
    } catch (e) {
      console.log('Failure at record', thisRecordNum)
    }
  }
) 
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