DeprecationWarning: Unhandled promise rejections are deprecated

Learn how to fix the 'Unhandled promise rejections are deprecated' warning and properly handle promise rejections in your automation code


DeprecationWarning: Unhandled promise rejections are deprecated

This warning appears when you have unhandled promise rejections in your code. Starting from Node.js 15, unhandled promise rejections will cause the process to terminate, making proper error handling essential.

Common Causes

  • Missing catch blocks: Promises without error handlers
  • 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 global promise rejection handler

// Add this at the start of your application
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
  // Handle the error appropriately
  // Don't exit the process, handle the error gracefully
});

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

2. Use async/await with proper error handling

async function runAutomation() {
  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);
    // Handle the error appropriately
  } finally {
    if (page) await page.close().catch(console.error);
    if (browser) await browser.close().catch(console.error);
  }
}

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

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. Use a promise wrapper utility

class PromiseWrapper {
  static async wrap(promise) {
    try {
      return await promise;
    } catch (error) {
      console.error('Promise error:', error);
      // Handle the error appropriately
      throw error; // Re-throw if needed
    }
  }
}

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

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 a browser manager class with error handling

class BrowserManager {
  constructor() {
    this.browser = null;
    this.page = null;
  }

  async initialize() {
    try {
      this.browser = await puppeteer.launch();
      this.page = await this.browser.newPage();
    } catch (error) {
      console.error('Initialization failed:', error);
      await this.cleanup();
      throw error;
    }
  }

  async cleanup() {
    try {
      if (this.page) await this.page.close();
      if (this.browser) await this.browser.close();
    } catch (error) {
      console.error('Cleanup failed:', error);
    } finally {
      this.page = null;
      this.browser = null;
    }
  }
}

// Usage
const manager = new BrowserManager();
try {
  await manager.initialize();
  // ... your automation code ...
} catch (error) {
  console.error('Automation failed:', error);
} finally {
  await manager.cleanup();
}

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 rejections are deprecated” warning and make your automation more robust.

Save days debugging
pptr crashes

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