In NestJS controller, I have a function that downloads files, saves them to the server's files, performs specific operations on these files, and then returns the processed file to the client. After all the operations are complete, I need to delete all the downloaded files.Everything works fine, but if some error occurs, the files are not deleted. I tried adding a delete function to the catch
and finally
block, but as I understand, it works before all operations in the try
block are completed and the files are not deleted. How can I fix this?
@Post(':id/export')
async potrfolioExport(
@Body() files: string[],
@Param('id') id: any,
@Res() res: Response
) {
const paths = files.map((elem) => `./uploads/${elem}.pptx`);
try {
await this.filesService.downloadFiles(files);
await this.filesService.downloadAdditionalFile('template.pptx');
await this.mergePres(paths);
res.download(`./uploads/output.pptx`);
await this.filesService.deleteFiles([...paths, './uploads/template.pptx', './uploads/output.pptx']);
} catch (error) {
console.error("Error: ", error.body);
await this.filesService.deleteFiles([...paths, './uploads/template.pptx', './uploads/output.pptx']);
res.status(500).json({ message: error.message, error: error });
}
}
async deleteFiles(filePaths: string[]): Promise<void> {
try {
const unlink = util.promisify(fs.unlink);
for (const filePath of filePaths) {
if (fs.existsSync(filePath)){
await unlink(filePath);
console.log(`${filePath} deleted`);
} else {
console.log(`${filePath} does not exist`);
}
}
} catch (error) {
console.error(`Deleting Error: ${error.message}`);
throw new Error(`Deleting presentation Error: ${error.message}`);
}
}
You aren't waiting for
res.download()
to complete so you're trying to delete./uploads/output.pptx
before you've finished sending it to the client.res.download()
takes an optional callback that will tell you when it's complete or you can promisify it so that you can thenawait
it and then only calldeleteFiles()
whenres.download()
has finished.For example, you could do this:
Or, here's a version where you promisify
res.download()
and consolidate error handling: