Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch an exception inside an event listener?

I use Puppeteer library to open an URL and process all requests' responses. Sometimes inside the event listener page.on('response') I need to throw an error like in the example below. But I'm unable to catch these exceptions in any way, I always got the unhandled promise rejection error. How can I handle these exceptions? I don't want to use process.on('unhandledRejection') because it doesn't solve my problem at all.

const puppeteer = require('puppeteer');

(async () => {
    try {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();

        page.on('response', (request) => {
            throw 'response error';
        });

        await page.goto('http://google.com/');

        browser.close();
    } catch (e) {}
})();
like image 825
pronngo Avatar asked Sep 18 '17 12:09

pronngo


People also ask

How do you catch an error in an event handler?

To catch a specific error, you can set the properties of the error in the Implementation tab of the error event handler by specifying the error code and mapping the error data to a specified variable.

Can event listeners be nested?

The final step, the callback function, can be written as a nested anonymous function inside the event listener or can be a designated function fully defined in a separate function. The callback handles the resulting work you want to happen after an event has occurred.

What is an event exception in Java?

The classic definition of an exception is an event that occurs during the execution of a program and that disrupts the normal flow of instructions. Java exceptions are specialized events that indicate something bad has happened in the application, and the application either needs to recover or exit.

Can you add event listener to a tag?

Add the event listener to the parent element you're adding the element to and then use event propogation to catch the event as it bubbles up. Either addEventListener to your newly created element, or listen to all clicks of parent element and determine which child element was clicked there.


2 Answers

Although the function of your page.on handler is located inside a try..catch block, the function is executed asynchronously and therefore any error thrown inside this function is not caught by the outer try..catch block.

You have to create another try..catch block inside your function.

Example

const puppeteer = require('puppeteer');

function handleError(err) {
    // ...
}

(async () => {
    try {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();

        page.on('response', (request) => {
            try { // inner try catch block to catch errors inside this function
                // ...
                throw 'response error';
            } catch (err) {
                // Handle the error here, or pass it to another function:
                handleError(err);
            }
        });

        await page.goto('http://google.com/');

        browser.close();
    } catch (e) {}
})();
like image 109
Thomas Dondorf Avatar answered Nov 07 '22 20:11

Thomas Dondorf


I would never put responses in event handlers as you will most definately run into the problem of express trying to send multiple responses to a user resulting in an error (except if you create a an event handler that manages if it has been called before and then supress sending a response but that is also not pretty). I would use a Promise.race condition.

This would wait for the first one of your promises to either reject or resolve. Even though your page.on cannot resolve that's ok because page.goto should do that or also reject.

So this would look somewhat like this

try {
  await Promise.race([
    new Promise((res,rej) => page.on('error', error => rej(error))),
    page.goto('http://google.com/')
  ]);
  // Do stuff if got succeeds
  browser.close();

catch (err) {
  // do stuff with your error
  browser.close();
}
like image 24
relief.melone Avatar answered Nov 07 '22 20:11

relief.melone