Getting "write EPIPE" error on AWS lambda

275 Views Asked by At

I followed this guide on https://medium.com/@bruce_39084/setting-up-prince-on-aws-lambda-and-api-gateway-4d524dcb035b but I want to just pass in a url instead of a html file. so I made some changes to the index.js and installed axios. I also used the latest prince lambda package as opposed to the 13.5 included in the guide.

    var execFile = require('child_process').exec;
    const axios = require('axios');
    
    function tinyMultipartParser(data) {
        // assume first line is boundary
        const lines = data.split("\r\n");
        const output = [];
        let in_body = false;
        lines.forEach(line => {
            output.push(line.trim());
        })
    
        return output.join("\n");
    
    }
    exports.handler = async (event, context, done) => {
    
        if (!event || !event.body) { return done(new Error("No data.")); }
        let body = event.body;
        if (event.isBase64Encoded) {
            body = Buffer.from(body, "base64").toString("ascii");
        }
    
        const response = await axios.get(body);
        body = response.data;
        const baseUrl = 'https://embed.notMyRealDomain.com'; // Replace with actual base URL
    
         // Replace relative URLs with absolute URLs
        body = body.replace(/href="([^"]+)"/g, (match, relativeURL) => {
            const absoluteURL = new URL(relativeURL, baseUrl).toString();
            return `href="${absoluteURL}"`;
        });
    
        body = body.replace(/src="([^"]+)"/g, (match, relativeURL) => {
            const absoluteURL = new URL(relativeURL, baseUrl).toString();
            return `src="${absoluteURL}"`;
        });
    
        let html = tinyMultipartParser(body);
        let child = execFile("./prince", ["-", "-o", "-"], function (err, stdout, stderr) {
            if (err) { throw new Error(err);}
            if (err === null && (m = stderr.toString().match(/prince:\s+error:\s+([^\n]+)/))) {
                throw new Error(m[1]);
            }
            done(null, {
                "isBase64Encoded": true,
                "statusCode": 200,
                "headers": { "Content-Type": "application/pdf" },
                "body": stdout.toString("base64")
            });
        });
        child.stdin.write(html);
        child.stdin.end();
    };

I got it to the point where the "html" variable right before it does exec on prince on both the html-file version and in the pass-in-a-url version the html variable is IDENTICAL but it only works on the html file version and errors in my pass in a url version. Through some searching it says the write EPIPE error happens when the client disconnects before the function is completed. That makes sense because when i dump the response in the client i just get "null" instead of what it usually says when there is an error but in cloud watch I get the write EPIPE error. I tried some things I found online about making it wait so and so seconds for a promise but that didn't seem to work at all.

0

There are 0 best solutions below