skip to Main Content

I set up a route that when placing all.pdf, it searches all the id’s in the database, generates a pdf of each and joins it in only one pdf of several pages. But when I put all.pdf it returns the error: error: invalid input syntax for type bigint: "all"

I also have the parameter with the limit, if I put all/15.pdf (15 is the number of id’s that will be pulled) it correctly pulls the 15 without any problem, but when I put all.pdf it returns this error. How can I solve?

router.get('/:database/:tipo/:ids/:limite?.pdf', async (req, res) => {
  const { database, tipo, ids, limite } = req.params;

  let idsArray;
  if (ids === "all") {
    const pool = new Pool({
      user: process.env.POSTGRES_USER,
      host: process.env.POSTGRES_HOST,
      database: database,
      password: process.env.POSTGRES_PASSWORD,
      port: process.env.POSTGRES_PORT,
    });

    let query = `SELECT DISTINCT id FROM controle_interno.${tipo} ORDER BY id ASC`;
    if (limite) {
      query += ` LIMIT ${limite}`;
    }
    const result = await pool.query(query);
    idsArray = result.rows.map(row => row.id);
  } else {
    idsArray = ids.split(",");
  }

  const pdfs = [];
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  for (let i = 0; i < idsArray.length; i++) {
    const id = idsArray[i];
    const url = `http://localhost:${port}/${database}/${tipo}/${id}`;
    console.log(url);
    try {
    await page.goto(url, {waitUntil: 'networkidle0'});
    await page.evaluate(() => {
      const button = document.getElementById('gerar-pdf');
      button.remove();
    });
  const pdfBytes = await page.pdf({ format: 'A4', printBackground: true, pageRanges: '1' });
  pdfs.push(await PDFDocument.load(pdfBytes));
} catch (err) {
  console.error(err.stack);
 }
}
  await browser.close();

  const mergedPdf = await PDFDocument.create();
  for (const pdf of pdfs) {
    const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
    copiedPages.forEach((page) => mergedPdf.addPage(page));
  }

  const pdfBytes = await mergedPdf.save();
  const filePath = path.join(__dirname, 'relatorio.pdf');

  await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
  await fs.promises.writeFile(filePath, pdfBytes);
  
  res.set({
    'Content-Type': 'application/pdf',
    'Content-Disposition': 'attachment; filename=relatorio.pdf',
    'Content-Length': pdfBytes.length
  });
  
  const stream = fs.createReadStream(filePath);
  stream.pipe(res);
  res.on('finish', async () => {
        // apaga o arquivo do diretório
        await fs.promises.unlink(filePath)});
  });

This is my code.

error: invalid input syntax for type bigint: "all"
    at Parser.parseErrorMessage (C:UsersTIDesktopcarta-api-mesquitanode_modulespg-protocoldistparser.js:287:98)
    at Parser.handlePacket (C:UsersTIDesktopcarta-api-mesquitanode_modulespg-protocoldistparser.js:126:29)
    at Parser.parse (C:UsersTIDesktopcarta-api-mesquitanode_modulespg-protocoldistparser.js:39:38)
    at Socket.<anonymous> (C:UsersTIDesktopcarta-api-mesquitanode_modulespg-protocoldistindex.js:11:42)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:324:12)
    at readableAddChunk (node:internal/streams/readable:297:9)
    at Readable.push (node:internal/streams/readable:234:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
  length: 98,
  severity: 'ERROR',
  code: '22P02',
  detail: undefined,
  hint: undefined,
  position: '47',
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'int8.c',
  line: '124',
  routine: 'scanint8'
}
C:UsersTIDesktopcarta-api-mesquitanode_modulespuppeteer-corelibcjspuppeteercommonExecutionContext.js:258
        throw new Error('Evaluation failed: ' + (0, util_js_1.getExceptionMessage)(exceptionDetails));
              ^

Error: Evaluation failed: TypeError: Cannot read properties of null (reading 'remove')
    at pptr://__puppeteer_evaluation_script__:3:16
    at ExecutionContext._ExecutionContext_evaluate (C:UsersTIDesktopcarta-api-mesquitanode_modulespuppeteer-corelibcjspuppeteercommonExecutionContext.js:258:15)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ExecutionContext.evaluate (C:UsersTIDesktopcarta-api-mesquitanode_modulespuppeteer-corelibcjspuppeteercommonExecutionContext.js:146:16)
    at async C:UsersTIDesktopcarta-api-mesquitasrcconfigRenderPdf.js:17:5

This is my error.

I tried creating an individual route with all.pdf to see if there were any conflicts with the limit, but it returned the same error.

I have another route but that generates a zip file, it works correctly with the parameter all.

This is my code to zip

router.get('/:database/:tipo/:ids/:limite?.zip', async (req, res) => {
    const { database, tipo, ids, limite } = req.params;
  
    let idsArray;
    if (ids === "all") {
      const pool = new Pool({
        user: process.env.POSTGRES_USER,
        host: process.env.POSTGRES_HOST,
        database: database,
        password: process.env.POSTGRES_PASSWORD,
        port: process.env.POSTGRES_PORT,
      });
  
      let query = `SELECT DISTINCT id FROM controle_interno.${tipo} ORDER BY id ASC`;
      if (limite) {
        query += ` LIMIT ${limite}`;
      }
      const result = await pool.query(query);
      idsArray = result.rows.map(row => row.id);
    } else {
      idsArray = ids.split(",");
    }
  
    const zip = new AdmZip();
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
  
    for (let i = 0; i < idsArray.length; i++) {
      const id = idsArray[i];
      const url = `http://localhost:${port}/${database}/${tipo}/${id}`;
      console.log(url);
      try {
      await page.goto(url, {waitUntil: 'networkidle0'});
      await page.evaluate(() => {
        const button = document.getElementById('gerar-pdf');
        button.remove();
      });
    const pdf = await page.pdf({ format: 'A4', printBackground: true, pageRanges: '1' });
      zip.addFile(`${id}.pdf`, pdf, `PDF para o ID ${id}`);
    } catch (err) {
      console.error(err.stack);
     }
    }
  
    await browser.close();
    const zipBuffer = zip.toBuffer();
  
    res.set({
      'Content-Type': 'application/zip',
      'Content-Disposition': `attachment; filename=${tipo}.zip`,
      'Content-Length': zipBuffer.length
    });
  
    res.send(zipBuffer);
  });

2

Answers


  1. Chosen as BEST ANSWER

    I managed to solve it, I had a route that generates a pdf individually like: router.get('/:database/:tipo/:id.pdf'.

    I was using router.get('/:database/:type/:ids/:limit?.pdf'. Changing the "ids" to all, it was like: /:database/:type/all.pdf. Causing conflict with the route quoted at the beginning. I changed the end of pdf to pdfs and it solved the problem, thanks everyone.


  2. The error message "invalid input syntax for type bigint: ‘all’" is because the PostgreSQL database is expecting a numerical value for the id column, but it is receiving the string "all" instead.

    To fix this error, you can add an if statement to check if the ids parameter is equal to "all". If it is, then you can skip the step of querying the database and generating PDFs for each individual ID. Instead, you can generate a PDF for all the IDs in the table. Here’s an example of how you can modify your code:

    if (ids === "all") {
      const pool = new Pool({
        user: process.env.POSTGRES_USER,
        host: process.env.POSTGRES_HOST,
        database: database,
        password: process.env.POSTGRES_PASSWORD,
        port: process.env.POSTGRES_PORT,
      });
    
      let query = `SELECT DISTINCT id FROM controle_interno.${tipo} ORDER BY id ASC`;
      if (limite) {
        query += ` LIMIT ${limite}`;
      }
      const result = await pool.query(query);
      idsArray = result.rows.map(row => row.id);
    } else {
      idsArray = ids.split(",");
    }
    

    In the above code, if the ids parameter is equal to "all", then it queries the database to get all the distinct IDs in the tipo table and sets idsArray to an array of those IDs. If the ids parameter is not equal to "all", then it splits the ids parameter by commas to get an array of individual IDs.

    As for the error "Evaluation failed: TypeError: Cannot read properties of null (reading ‘remove’)", it seems to be happening because the button variable is null. This could be because the button with the ID "gerar-pdf" does not exist on the page. You can add a check to ensure that the button exists before trying to remove it. Here’s an example:

    await page.goto(url, {waitUntil: 'networkidle0'});
    const button = await page.$('#gerar-pdf');
    if (button) {
      await button.evaluate(button => button.remove());
    }
    

    In the above code, it uses page.$ to find the button with the ID "gerar-pdf". If the button exists, then it removes it. If the button does not exist, then it skips that step.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search