chrome-aws-lambda
chrome-aws-lambda copied to clipboard
[BUG] PDF generation fails with blank error
Environment
-
chrome-aws-lambda
Version: 5.2.1 -
puppeteer
/puppeteer-core
Version: 5.2.1 - OS: Linux
- Node.js Version: 13.x
- Lambda / GCF Runtime: nodejs12.x
Expected Behavior
Should create pdf
Current Behavior
I get error
{ error: {} }
Steps to Reproduce
import { APIGatewayProxyHandler } from 'aws-lambda';
import 'source-map-support/register';
import * as handlebars from 'handlebars';
import * as AWS from 'aws-sdk';
import chromium from "chrome-aws-lambda";
import puppeteer from "puppeteer-core";
const createHtml = async (template) => {
const s3 = new AWS.S3();
let Bucket = process.env.TEMPLATES_BUCKET;
let Key = `proposal_template.html`;
let { Body } = await s3.getObject({ Bucket, Key }).promise()
.catch(e => Promise.reject(e));
let html = Body.toString();
html = handlebars.compile(html)(template.proposal);
return html;
}
const htmlToPdf = async (html) => {
let browser: any = null;
let pdfBuffer: Buffer | null = null;
try {
browser = await chromium.puppeteer.launch({
args: chromium.args,
defaultViewport: chromium.defaultViewport,
executablePath: await chromium.executablePath,
headless: true,
ignoreHTTPSErrors: true,
})
const page = await browser.newPage();
await page.setContent(html);
pdfBuffer = await page.pdf({
format: "A4"
});
} catch (error) {
throw error
} finally {
if (browser !== null) {
await browser.close();
}
}
return pdfBuffer;
}
const uploadToS3 = async (pdfBuffer: Buffer, BuketKey) => {
const s3SecI = new AWS.S3();
let Bucket = process.env.PROPOSALS_BUCKET;
let Key = `${BuketKey}.pdf`;
const s3Data = await s3SecI.upload({ Bucket, Key, Body: pdfBuffer, ACL: 'public-read' }).promise()
.catch(e => Promise.reject(e));
return s3Data.Location;
}
export const createHtmlToPdf: APIGatewayProxyHandler = async (event, _context) => {
const requestBody = JSON.parse(JSON.stringify(event.body));
const templateData = requestBody.templateData;
return createHtml(templateData)
.then((html) => {
return htmlToPdf(html);
})
.then((pdf) => {
const Key = `${templateData.proposalId}/${templateData.versionId}`;
return uploadToS3(pdf, Key);
})
.then((pdfLink) => {
return {
statusCode: 200,
body: JSON.stringify({
pdfLink
}, null, 2)
};
})
.catch((err) => {
return {
statusCode: 200,
body: JSON.stringify({
message: 'Failed',
error: err
}, null, 2)
};
})
}
Possible Solution
I checked the createHtml, and uploadToS3 functions separately they works as normal.... but htmlPdf fails. Specifically it fails at
browser = await chromium.puppeteer.launch({
args: chromium.args,
defaultViewport: chromium.defaultViewport,
executablePath: await chromium.executablePath,
headless: true,
ignoreHTTPSErrors: true,
});
@mithundas79 If the problematic line is indeed what you are saying (browser = await chromium.puppeteer.launch({...
) then most of the code you are showing us is likely to be irrelevant. My guess would be that you are having a configuration error / missing dependency, and you cannot launch the browser. That's all.
If that is not the case, please reduce your example because it has too many moving parts.
Hard-code the HTML as a plain string in the JavaScript code. Get rid of everything specific to the Lambda and write the PDF directly to disc by passing a path: '/tmp/myexample.pdf',
to the await page.pdf({...})
call. We must be able to test everything locally and without sam
.
If that still doesn't reveal where the problem is, try eliminating as much of the HTML and the JavaScript code as possible.
Long story short: Please try to make your example minimal.