Pdfkit: how to solve stream.push() after EOF

Created on 21 Apr 2019  路  10Comments  路  Source: foliojs/pdfkit

stream.push() after EOF

Most helpful comment

So my problem was that I define document object globally in my code. And when lambda tries to create another pdf, it is using current stream object which causes this error.

const doc = new PDFDocument({ size: 'A4' });

When i moved creation of new document object inside the function, it initializes a new object each time, and the error is gone. Pdfkit now works properly.
Maybe that can help you as well.

All 10 comments

Is this the error?

Error: stream.push() after EOF at readableAddChunk (_stream_readable.js:240:30) at PDFDocument.Readable.push (_stream_readable.js:208:10) at PDFDocument._write (/srv/node_modules/pdfkit/js/pdfkit.js:4368:10) at PDFReference.finalize (/srv/node_modules/pdfkit/js/pdfkit.js:204:19) at PDFReference.end (/srv/node_modules/pdfkit/js/pdfkit.js:183:17) at PDFDocument.link (/srv/node_modules/pdfkit/js/pdfkit.js:4011:17) at PDFDocument._fragment (/srv/node_modules/pdfkit/js/pdfkit.js:3403:12) at PDFDocument._line (/srv/node_modules/pdfkit/js/pdfkit.js:3320:10) at emitThree (events.js:141:20) at LineWrapper.emit (events.js:217:7)

Looking for a solution as well.

I am using the library in aws lambda, first request creates pdf document properly but after second request i get the same error.

pdfkit is asynchronous so the aws lambda handler must be configured accordingly.

You can try something like: https://github.com/foliojs/pdfkit/issues/975#issuecomment-495013521

So my problem was that I define document object globally in my code. And when lambda tries to create another pdf, it is using current stream object which causes this error.

const doc = new PDFDocument({ size: 'A4' });

When i moved creation of new document object inside the function, it initializes a new object each time, and the error is gone. Pdfkit now works properly.
Maybe that can help you as well.

@gokertanrisever , I have same issue like you.
could you show some code to ignore this problem ?

@Chinnatip, So I removed the irrelevant lines from my code, as a summary:

const fs = require('fs');
const PDFDocument = require('pdfkit');

async function createPdf() {
    return new Promise((resolve, reject) => {
        const doc = new PDFDocument({ size: 'A4' });  // Create a new instance 
        const fileName = "/tmp/test.pdf";
        let stream = fs.createWriteStream(fileName);
        doc.pipe(stream);
        doc.text('Some text here!')
        doc.end();
        resolve({ fileName, stream });
    });

}

exports.handler = function (event, context) {
    process.setMaxListeners(0);
    if (event != null) {
        createPdf(pageA, pageB, employeeId)   // Call the function inside handler
            .then(({ fileName, stream }) => {
                stream.on('finish', () => {
                    email.sendMail(mail, fileName)
                        .then(res => {
                            stream.end();
                            fs.unlinkSync(fileName);
                            context.done(null, 'Email Sent!');
                        })
                        .catch(err => {
                            context.done("Email could not be sent!\n" + err);
                        })
                });
                stream.on('error', () => {
                    console.log(err);
                    stream.end();
                });
            })
            .catch(err => {
                console.log(err);
                context.done("PDF cannot be created!");
            });
    }
    else {
        console.log('No event object');
        context.done("error");
    }
};

just delete doc.end();

Anyone could solve this problem? Help us!

Does anyone find the solution?

Most probably you are using doc .end() outside a lambda function. Make sure you don't try to write to the doc, after doc.end() was already called.

```typescript
const xhr = new XMLHttpRequest();
xhr.open("get", "/assets/images/logo.png", true);
// Load the data directly as a Blob.
xhr.responseType = "blob";
xhr.onload = function () {
const blob = this.response;
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
const base64 = reader.result;
console.log("base64 image :: ", base64);

    doc.image(base64, 0, 15, { width: 300 })
      .text("Your text here...", 0, 0);

    // make sure to call doc.image() or other doc writing functions before doc.end() by calling doc.end() inside lambda function. doc.end() should be called only after all writes happend already.
    doc.end();
  }
};
xhr.send();
Was this page helpful?
0 / 5 - 0 ratings