UnhandledPromiseRejectionWarning: Unhandled promise rejection

Learn how to fix the 'Unhandled promise rejection' error when promises are not properly handled in your automation code


UnhandledPromiseRejectionWarning: Unhandled promise rejection

This error occurs when a Promise is rejected but there’s no error handler to catch the rejection. This is a common issue in asynchronous code, especially when working with Puppeteer’s Promise-based API.

Common Causes

  • Missing error handlers: Promises without catch blocks
  • Async function errors: Unhandled errors in async functions
  • Promise chain issues: Broken promise chains
  • Event handler errors: Unhandled errors in event handlers
  • Resource cleanup errors: Errors during browser/page cleanup

Solutions

1. Implement proper error handling

async function runAutomation() {
  try {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    
    await page.goto('https://example.com');
    // ... your automation code ...
    
    await browser.close();
  } catch (error) {
    console.error('Automation failed:', error);
    // Handle the error appropriately
  }
}

// Don't forget to handle the promise
runAutomation().catch(error => {
  console.error('Unhandled error:', error);
});

2. Use async/await with try/catch

async function safeOperation(operation) {
  try {
    await operation();
  } catch (error) {
    console.error('Operation failed:', error);
    // Handle the error appropriately
  }
}

// Usage
safeOperation(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
});

3. Implement promise error boundaries

function withErrorBoundary(promise) {
  return promise.catch(error => {
    console.error('Error caught by boundary:', error);
    // Handle the error appropriately
    throw error; // Re-throw if needed
  });
}

// Usage
withErrorBoundary(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
});

4. Handle event listener errors

const browser = await puppeteer.launch();

// Handle browser events
browser.on('disconnected', () => {
  console.log('Browser disconnected');
}).on('error', error => {
  console.error('Browser error:', error);
});

// Handle page events
page.on('error', error => {
  console.error('Page error:', error);
}).on('pageerror', error => {
  console.error('Page error:', error);
});

5. Implement proper cleanup with error handling

async function cleanup(browser, page) {
  try {
    if (page) await page.close();
  } catch (error) {
    console.error('Error closing page:', error);
  }
  
  try {
    if (browser) await browser.close();
  } catch (error) {
    console.error('Error closing browser:', error);
  }
}

// Usage
let browser;
let page;

try {
  browser = await puppeteer.launch();
  page = await browser.newPage();
  await page.goto('https://example.com');
  // ... your automation code ...
} catch (error) {
  console.error('Automation failed:', error);
} finally {
  await cleanup(browser, page);
}

6. Use process-level error handlers

// Handle unhandled promise rejections
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
  // Handle the error appropriately
});

// Handle uncaught exceptions
process.on('uncaughtException', (error) => {
  console.error('Uncaught Exception:', error);
  // Handle the error appropriately
  process.exit(1);
});

Still Encountering Issues?

If you’re still having trouble with unhandled promise rejections, you can use a visual testing tool like Buglesstack to debug your automation and track promise rejections.

try {
	await page.goto('https://www.google.com/search?q=puppeteer');		
	await page.waitForSelector('[name="q"]');
}
catch (error) {
	// Prepare buglesstack data
	const buglesstackData = {
		url: page.url(),
		screenshot: await page.screenshot({ encoding: 'base64' }),
		html: await page.content(),
		metadata: {},
		message: error.message,
		stack: error.stack
	};

	// Get your access token from https://app.buglesstack.com
	const ACCESS_TOKEN = 'HERE_YOUR_ACCESS_TOKEN';

	// Send error to buglesstack
	await axios.post('https://app.buglesstack.com/api/v1/crashes', buglesstackData, {
		headers: {
			Authorization: `Bearer ${ACCESS_TOKEN}`,
			'Content-Type': 'application/json'
		}
	});
		
	// Re-throw the error to propagate it
	throw error;
}

By implementing proper error handling and promise management, you can resolve the “Unhandled promise rejection” error and make your automation more robust.

Save days debugging
pptr crashes

Speed up production debugging with instant visualizations of your puppeteer crashes.