How to catch timeout exceptions in Puppeteer when waiting for page elements

I’m working with Puppeteer and running into an issue with error handling. When I submit a form by clicking a submit button, the page should display results if the input is valid. Here’s my current code:

await browser.click('input[type="submit"][id="search-btn"]')

await browser.waitForSelector('.result-container .data-display').catch(error => console.log(error))

await browser.evaluate((query) => {
    console.log(query + " gives: " + document.querySelector('.result-container .data-display .value').textContent)
}, searchQuery)

This works fine when the input data is correct and valid. However, when I enter invalid data, the expected element never shows up on the page. There’s no page navigation or loading that happens in this case.

Since the element I’m waiting for doesn’t exist, Puppeteer throws this error:

Navigation Timeout Exceeded: 30000ms exceeded

This error crashes my entire script. I need to figure out how to properly catch this timeout error so I can handle invalid inputs gracefully and call a different function instead of letting the program crash. What’s the best way to handle this situation?

had the same problem last week. don’t wait for just one element - check for multiple conditions instead. after clicking submit, use Promise.race() to wait for either the success element OR an error message: Promise.race([browser.waitForSelector('.result-container'), browser.waitForSelector('.error-msg')]). this prevents hanging forever when invalid data triggers an error instead of results. much cleaner than try/catch.

That timeout error is expected when elements don’t exist. Your .catch() approach won’t work here because the timeout exception kills the entire execution flow. I’ve run into this before - wrapping the whole waitForSelector in a try-catch block works way better. You can handle both successful detection and timeouts cleanly. Try this: await browser.click(‘input[type=“submit”][id=“search-btn”]’); try { await browser.waitForSelector(‘.result-container .data-display’, { timeout: 10000 }); await browser.evaluate((query) => { console.log(query + " gives: " + document.querySelector(‘.result-container .data-display .value’).textContent); }, searchQuery); } catch (error) { if (error.name === ‘TimeoutError’) { console.log(‘Invalid input detected - no results found’); } else { throw error; } } Also, drop that timeout from 30 seconds to something like 10 seconds. Much better user experience.

The problem is waitForSelector has its own timeout that bypasses your Promise chain when it fails. Your .catch() only handles rejected promises, but Puppeteer’s timeout throws an unhandled exception before your catch can grab it. I usually set a custom timeout directly in waitForSelector and wrap everything in async/await with proper exception handling. Try this: await browser.waitForSelector('.result-container .data-display', { timeout: 5000 }).then(() => { // success logic }).catch(() => { // handle invalid input case }). Set a shorter timeout and structure the promise chain right. You’ll catch invalid inputs fast without waiting 30 seconds, and your script won’t crash.