0

我已经使用自定义容器映像构建了一个 AWS Lambda 函数。我正在尝试使用 Libreoffice 将 excel 文件转换为 pdf - 从 S3 获取文件并将其保存为文件并将其转换为 pdf,然后将其上传回 S3。

这里是代码。

const fs = require('fs');
const getStream = require('get-stream');
const { Readable } = require('stream')
const { S3Client, GetObjectCommand, PutObjectCommand } = require("@aws-sdk/client-s3");
const libre = require('libreoffice-convert');
const path = require('path');

exports.handler = async (event) => {

    const bucket = event.queryStringParameters.bucket;
    const file = event.queryStringParameters.file;
    const convertedFile = event.queryStringParameters.convertedFile;

    if (event.queryStringParameters['warmup'] !== undefined) {
        return {
            result: true,
            message: 'warmed up'
        }
    }

    const client = new S3Client({ region: "ap-south-1" });
    const command = new GetObjectCommand({ Bucket: bucket, Key: file });
    const response = await client.send(command);
    const objectData = response.Body;    
    const writeStream = fs.createWriteStream("/tmp/sample.xlsx");
    objectData.pipe(writeStream);
    
    var end = new Promise((resolve, reject) => {
        objectData.on('close', resolve(true));
        objectData.on('end', resolve(true));
        objectData.on('error', reject(false));
    });

    let completed = await end;

    if (completed) {        
        const extend = '.pdf'        
        const outputPath = `/tmp/sample${extend}`;  
        const enterPath = '/tmp/sample.xlsx';

        var readingFile = new Promise((resolve, reject) => {
            fs.readFile(enterPath, (err, data)=>{
                if (err) {
                    reject(false);
                }

                resolve(data);
            });
        });
        
        var fileData = await readingFile;

        var converting = new Promise((resolve, reject) => {
            libre.convert(fileData, extend, undefined, (err, done) => {
                if (err) {
                    reject(false)
                }
    
                fs.writeFileSync(outputPath, done);
                resolve(true)
            });
        })

        var converted = await converting;

        if (converted) {
            var convertedFileStream = fs.createReadStream(outputPath);
            const uploadCommand = new PutObjectCommand({ Bucket: bucket, Key: convertedFile, Body: convertedFileStream });
            const lastResponse = await client.send(uploadCommand);

            const returnResponse = {
                result: true,
                message: 'success',
                bucket: event.queryStringParameters.bucket,
                file: event.queryStringParameters.file,
                convertedFile: event.queryStringParameters.convertedFile
            };

            if (event.queryStringParameters['returnEvent'] !== undefined) {
                returnResponse['returnEvent'] = event;
            }

            return returnResponse;
        }
    }

    return completed;
};

但是,我有时会收到此错误。有时,它是成功的,但有时它会抛出这个错误。

{
    "errorType": "Error",
    "errorMessage": "false",
    "stack": [
        "Error: false",
        "    at _homogeneousError (/function/node_modules/aws-lambda-ric/lib/Runtime/CallbackContext.js:56:16)",
        "    at postError (/function/node_modules/aws-lambda-ric/lib/Runtime/CallbackContext.js:72:34)",
        "    at done (/function/node_modules/aws-lambda-ric/lib/Runtime/CallbackContext.js:99:13)",
        "    at fail (/function/node_modules/aws-lambda-ric/lib/Runtime/CallbackContext.js:113:13)",
        "    at /function/node_modules/aws-lambda-ric/lib/Runtime/CallbackContext.js:148:24",
        "    at processTicksAndRejections (internal/process/task_queues.js:97:5)"
    ]
}

我不太了解 Nodejs,所以我认为如果代码没有以正确的方式编写。有什么想法我在这里做错了吗?

4

1 回答 1

0

就像@hoangdv 一样,当我记录错误时,我才知道保存到磁盘的文件不正确。因此,我将保存的代码区域更改为这样,然后它就起作用了。

    const client = new S3Client({ region: "ap-south-1" });
    const command = new GetObjectCommand({ Bucket: bucket, Key: file });
    const { Body } = await client.send(command);

    await new Promise((resolve, reject) => {
        Body.pipe(fs.createWriteStream(filePath))
            .on('error', err => reject(err))
            .on('close', () => resolve())
    })
    
    const excelFile = fs.readFileSync(filePath);
于 2021-07-08T14:26:44.790 回答