如何在嵌套异步函数中捕获错误

Posted

技术标签:

【中文标题】如何在嵌套异步函数中捕获错误【英文标题】:How catch errors in nested async functions 【发布时间】:2022-01-14 22:02:28 【问题描述】:

我正在尝试在嵌套异步函数中捕获错误,以便在出现错误时进行回滚。

所以我有我的第一个 try catch,然后在其中我调用一个调用另一个函数的函数,最后一个函数应该抛出一个错误,我认为第一个 try bloc 会捕获抛出错误,但他没有。这是我的代码:

第一个 try/catch 的函数:

exports.add = (req, res) => 
    const  product, type  = req.body

    try 
        switch (type) 
            case ProductsTypes.TRACK:
                addTrack(product, req.files)
                res.status(200).json( message: 'SUCCESS !' )
                break
            default:
                res.status(400).json( message: 'INVALID TYPE !' )
        
     catch (error) 
        // ROLLBACK HERE
        res.status(400).json( message: "Error Exception, Need to rollback", error )
    

我想捕获错误并将其返回顶部的函数

const addTrack = (product, files) => 
    const imageFile = files[NamesAddTrackForm.TRACK_IMAGE][0]
    const audioFile = files[NamesAddTrackForm.TRACK_AUDIO][0]
    const stemsZip = files[NamesAddTrackForm.TRACK_STEMS][0]

    FilesFormater.resizeImage(imageFile, 500, 500) // I thought this function throw an exception

我抛出错误的函数:

resizeImage = (file, width, height) => 
    try 
        sharp(file.path)
            .resize(width, height)
            .jpeg( quality: 90 )
            .toBuffer((err, buffer) => 
                fs.writeFileSync(file.path, buffe, (err) =>  // I simulate an error here (buffe) instead (buffer)
                    if (!err) 
                        throw Error(err)
                    
                )
            )
     catch (error) 
        throw Error(error)
    

我想知道如何处理此类错误以将其发送回第一个错误,因为我想在我的其他文件中使用此逻辑来回滚操作,例如插入数据库,或者创建文件,如果在代码处理过程中出现错误,否则我会得到不合逻辑的数据

【问题讨论】:

您是否尝试过将 addTrack 中的 resizeImage 函数调用也封装到 try...catch 块中? 【参考方案1】:

如果您想从异步操作中捕获错误,则需要使 resizeImage 返回 Promise。

另外,你需要在函数中添加async关键字,这样你才能使用await

您可以尝试如下:(代码未测试。)

const fs = require("fs").promises;

class FilesFormater 
    static resizeImage = async (file, width, height) => 
        try 
            const  data  = await sharp(file.path)
                .resize(width, height)
                .jpeg( quality: 90 )
                .toBuffer();

            await fs.writeFile(file.path, data);
         catch (error) 
            throw new Error(error);
        
    ;


const addTrack = (product, files) => 
    const imageFile = files[NamesAddTrackForm.TRACK_IMAGE][0];
    const audioFile = files[NamesAddTrackForm.TRACK_AUDIO][0];
    const stemsZip = files[NamesAddTrackForm.TRACK_STEMS][0];

    return FilesFormater.resizeImage(imageFile, 500, 500); // a Promise is return.
;

exports.add = async (req, res) => 
    const  product, type  = req.body;

    try 
        switch (type) 
            case ProductsTypes.TRACK:
                await addTrack(product, req.files); // await the Promise
                res.status(200).json( message: "SUCCESS !" );
                break;
            default:
                res.status(400).json( message: "INVALID TYPE !" );
        
     catch (error) 
        // ROLLBACK HERE
        res.status(400).json(
            message: "Error Exception, Need to rollback",
            error,
        );
    
;

【讨论】:

以上是关于如何在嵌套异步函数中捕获错误的主要内容,如果未能解决你的问题,请参考以下文章

捕获回调函数引发的错误

将异步操作分派到 redux-saga 后如何捕获 redux 存储中的更改

如何在构造函数中捕获异步方法的异常?

在 Node/Express 的异步函数中捕获错误

VBA如何捕获请求超时错误?

异步 - 等待 JavaScript:无法从错误对象中捕获错误详细信息 [重复]