Fastify 在文件上传时抛出 Unfulfilled Promise 错误

Fastify Throws Unfulfilled Promise Error On File Uplaod

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

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] 进程强制结束

看来后台不知道请求什么时候结束,强行终止了上传进程。不知道从这里去哪里,所以任何帮助将不胜感激。

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

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

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

另外,除非你打算对潜在捕获的错误做任何有意义的事情,否则你可以去掉 try/catch 块,这样处理函数中抛出的任何错误都会被 Fastify 捕获(并可能记录下来)取决于您的日志级别设置),然后用代码 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 只是一个 属性 访问而不是函数调用 return 一个可以等待的承诺。