diff --git a/export/src/handler.ts b/export/src/handler.ts index 22d750c57a..d9c5f26053 100644 --- a/export/src/handler.ts +++ b/export/src/handler.ts @@ -1,6 +1,6 @@ import * as Sentry from '@sentry/node'; import type { VercelApiHandler, VercelRequest, VercelResponse } from '@vercel/node'; -import type { Page } from 'puppeteer-core'; +import type { Browser, Page } from 'puppeteer-core'; import * as render from './render-serverless'; import config from './config'; @@ -56,9 +56,10 @@ export function makeExportHandler( // Prepare browser for export const url = config.page; + let browser: Browser; let page: Page; try { - page = await render.open(url); + ({ browser, page } = await render.open(url)); } catch (error) { if (error.message.includes('ERR_CONNECTION_REFUSED')) { throw new HttpError( @@ -70,11 +71,12 @@ export function makeExportHandler( throw new HttpError(500, 'Cannot start browser', error); } - // Export - await performExport(response, page, data); - - // Cleanup - await page.close(); + try { + // Export + await performExport(response, page, data); + } finally { + await browser.close(); + } } catch (error) { const eventId = Sentry.captureException(error.original || error); diff --git a/export/src/render-serverless.ts b/export/src/render-serverless.ts index ce9d287d55..540733c6c5 100644 --- a/export/src/render-serverless.ts +++ b/export/src/render-serverless.ts @@ -1,5 +1,5 @@ import chromium from '@sparticuz/chromium'; -import puppeteer, { Page } from 'puppeteer-core'; +import puppeteer, { Browser, Page } from 'puppeteer-core'; import { resolveChromeExecutable } from './chrome-executable'; import { getModules } from './data'; @@ -23,7 +23,7 @@ async function setViewport(page: Page, options: ViewportOptions = {}) { }); } -export async function open(url: string) { +export async function open(url: string): Promise<{ browser: Browser; page: Page }> { const executablePath = await resolveChromeExecutable(() => chromium.executablePath()); chromium.setGraphicsMode = false; @@ -35,11 +35,16 @@ export async function open(url: string) { headless: 'shell', }); - const page = await browser.newPage(); - await page.goto(url, { waitUntil: 'load' }); - await setViewport(page); + try { + const page = await browser.newPage(); + await page.goto(url, { waitUntil: 'load' }); + await setViewport(page); - return page; + return { browser, page }; + } catch (error) { + await browser.close(); + throw error; + } } async function injectData(page: Page, data: ExportData) {