【问题标题】:Fastify Throws Unfulfilled Promise Error On File UplaodFastify 在文件上传时抛出未履行的承诺错误
【发布时间】:2021-12-31 20:45:10
【问题描述】:

我正在学习 Fastify,所以我编写了一个简单的程序来使用 Fastify-Formidable 上传文件。该文件已成功上传并在 mv 包的帮助下移动到其目标目录。然而,当这种情况发生时,Fastify 会在控制台中抛出一个未处理的 Promise 错误。我的代码是:

const insertManyWorkers = async (request, reply) => {      
  try {
    await request.parseMultipart();    
    let oldpath = await request.files.picture.path;
    let uploadDir = '/home/hamza/Documents/Web-Projects/Personal/test/img/' + request.files.picture.name;   
    await mv(oldpath, uploadDir, {
      mkdirp: true
    }, function(err) {    
      if (err) {
        reply.send(err);    
      } else {
        reply.code(200).send('uploaded')    
      }
    });   
  } catch (error) {
    console.log(error);
    reply.send(error)    
  };
};

错误如下:

01:17:24 ✨ incoming request POST xxx /workers/insert 01:17:24 ???? Promise may not be fulfilled with 'undefined' when statusCode is not 204 FastifyError: Promise may not be fulfilled with 'undefined' when statusCode is not 204 at /home/user-1/Documents/Web-Projects/test/node_modules/fastify/lib/wrapThenable.js:30:30 at processTicksAndRejections (node:internal/process/task_queues:96:5) { "err": { "type": "FastifyError", "message": "Promise may not be fulfilled with 'undefined' when statusCode is not 204", "stack": "FastifyError: Promise may not be fulfilled with 'undefined' when statusCode is not 204\n    at /home/hamza/Documents/Web-Projects/Personal/test/node_modules/fastify/lib/wrapThenable.js:30:30\n at processTicksAndRejections (node:internal/process/task_queues:96:5)", "name": "FastifyError", "code": "FST_ERR_PROMISE_NOT_FULFILLED", "statusCode": 500 } } 01:17:24 ✨ request completed 18ms [fastify-cli] process forced end 01:17:30 ✨ Server listening at http://0.0.0.0:5000

此外,Fastify 还会在文件上传几毫秒后记录[fastify-cli] 进程强制结束

后端似乎不知道请求何时结束,因此强行终止了上传过程。不知道从这里去哪里,所以任何帮助将不胜感激。

【问题讨论】:

    标签: node.js mv formidable fastify fastify-multipart


    【解决方案1】:

    当使用异步路由处理程序(在您的情况下为insertManyWorkers)时,Fastify 期望处理程序返回的 Promise 使用定义的值(将作为回复正文发送)解析,除非您将回复状态代码明确设置为204,表示“无内容”。

    另一个问题是您的代码正在等待mv,这是一个不返回承诺的基于回调的函数。为了在 async 函数中使用 await 调用 mv,您可以使用 promisify:

    const mv = require('mv');
    const util = require('util');
    const mvPromisified = util.promisify(mv);
    

    另外,除非你打算对可能捕获的错误做任何有意义的事情,否则你可以去掉 try/catch 块,这样处理函数中抛出的任何错误都会被 Fastify 捕获(并且可能由 Pino 记录,具体取决于您的日志级别设置),然后响应代码 500。因此,您的 insertManyWorkers 函数可能如下所示:

    const insertManyWorkers = async (request, reply) => {      
      await request.parseMultipart();    
      let oldpath = await request.files.picture.path;
      let uploadDir = '/home/hamza/Documents/Web-Projects/Personal/test/img/' + request.files.picture.name;   
      await mvPromisified(oldpath, uploadDir, {
        mkdirp: true
      })
      return 'uploaded';
    };
    

    还值得注意的是let oldpath = await request.files.picture.path 中的await 是不必要的,因为request.files.picture.path 只是一个属性访问,而不是一个返回可以等待的承诺的函数的调用。

    【讨论】:

    • 非常感谢您的详细解答。真的很有帮助。
    猜你喜欢
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-04
    • 2018-02-19
    • 2016-02-26
    • 2016-09-13
    相关资源
    最近更新 更多