Nestjs busboy接收到文件后出现enoint错误
我正在处理一个遗留项目,其中MP4文件从带有Nestjs busboy接收到文件后出现enoint错误,nestjs,busboy,enoent,Nestjs,Busboy,Enoent,我正在处理一个遗留项目,其中MP4文件从带有axios的React应用程序逐个上传到EC2实例上带有busboy的NestJS API。然后,文件被上传到S3存储桶 当AWS S3库尝试加载文件时,有时会出现明显的“随机”错误: warn module: videoservice method: saveTostream message: Error on Upload Success callback { [Error: ENOENT: no such file or directo
axios
的React应用程序逐个上传到EC2实例上带有busboy
的NestJS API。然后,文件被上传到S3存储桶
当AWS S3库尝试加载文件时,有时会出现明显的“随机”错误:
warn
module: videoservice
method: saveTostream
message: Error on Upload Success callback
{ [Error: ENOENT: no such file or directory, open 'file.mp4'] errno: -2, code: 'ENOENT', syscall: 'open', path: 'file.mp4' }
(node:26886) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open 'file.mp4'
(node:26886) UnhandledPromiseRejectionwarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catc h(). (rejection id: 20)
以下是片段:
API上载端点
@Post('upload/:id')
@ApiOperation({ ... })
@ApiResponse({ status: 201, type: Video })
@ApiConsumes('multipart/form-data')
@ApiImplicitFile({ name: 'file', required: true })
@ApiCreatedResponse({ type: UploadResponseDto })
async upload(
@Decoded() decoded: any,
@Param('id') videoId: number,
@Query('fileSize') fileSize :number,
@Req() req: Request,
@Res() res: Response,
@Body() uploadDto: UploadDto,
): Promise<any> {
try {
const busboy = new Busboy({
headers: req.headers,
});
const data = new Map();
const writtenFiles = [];
let upload;
busboy.on('field', (fieldname, val) => {
data.set(fieldname, val);
});
busboy.on(
'file',
async (fieldname, file, filename, encoding, mimetype) => {
try {
data.set('filename', filename);
data.set('mimetype', mimetype);
data.set('encoding', encoding);
const filepath = path.join(fieldname + path.extname(filename));
upload = filepath;
const writeStream = fs.createWriteStream(filepath);
file.pipe(writeStream);
const promise = new Promise((resolve, reject) => {
file.on('end', () => {
writeStream.end();
});
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});
writtenFiles.push(promise);
} catch (err) {
this.logger.error(log('busboy on file', err.message));
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).send({
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
message: err.message,
});
}
},
);
busboy.on('error', err => {
this.logger.warn(log('busboy on error', err.message));
});
busboy.on('finish', async () => {
await Promise.all(writtenFiles);
res.status(HttpStatus.CREATED).send('OK');
await this.bucketService.saveStream( // Next snippet
fs.createReadStream(upload),
data.get('filename'),
data.get('mimetype'),
data.get('fileSize'),
+data.get('programId'),
+data.get('videoId')
);
return;
fs.unlinkSync(upload);
});
req.pipe(busboy);
} catch (err) {
this.logger.error(log('catch', err.message));
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).send({
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
message: err.message,
});
}
}
在某个时刻,我认为这可能是因为EC2上的临时文件的名称总是相同的:file.mp4
,当两个文件同时上载时,完成时的第一个文件会删除该文件(fs.unlinkSync(upload);
在端点上),而另一个正在进行的进程则没有它,因此,当尝试上载时,此进程将找不到它。但事实并非如此,因为我进行了测试,确保文件一个接一个地上传。但是,我还通过在控制器上更改来确保名称始终不同:
constfilepath=path.join(fieldname+path.extname(filename))代码>
借
constfilepath=path.join(Math.floor(Math.random()*10000)+path.extname(filename))代码>
但错误仍在发生。发生的另一件奇怪的事情是,在我的机器中,我可以看到(ls
)上传的文件,但在EC2中却看不到
事实:
- EC2:t2.xlarge(大约免费4GB)
- 操作系统:Ubuntu18
- 节点版本:10.21.0
- 平均文件大小:2GB
- 依赖关系
"archiver": "^3.1.1",
"async-busboy": "^0.7.0",
"aws-sdk": "^2.553.0",
"axios": "^0.19.0",
"body-parser": "^1.19.0",
"busboy": "^0.3.1",
"archiver": "^3.1.1",
"async-busboy": "^0.7.0",
"aws-sdk": "^2.553.0",
"axios": "^0.19.0",
"body-parser": "^1.19.0",
"busboy": "^0.3.1",