使用异步/等待捕获异步和同步功能的错误

时间:2019-02-06 17:39:33

标签: node.js exception async-await

我有一个路由器,它需要能够同时调用异步功能和同步功能。我将以下代码设置为执行程序:

async exec(method, path, params, payload) {
    const route = this.get(method, path);

    if (!route) throw new RequestError(422, 'Route [' + path + '] not found');

    // Recheck, just to make sure
    if (typeof route._callback !== 'function')
        throw new AppError('Callback defined for route [' + route.name + '] is not a function');

    this._logger('info', 'Route [' + path + '] recieved.  Executing [' + route.callback + ']', route.params);

    let results;
    try {
        results = route._callback(Object.assign(params || {}, route.params || {}), payload);
        // If the results is a promise, then we await the promise results
        if (results.then && typeof results.then === 'function') {
            await results;
        }
    } catch (err) {
        throw new AppError(err.message, err);
    }

    return results;
}

在调用函数中,我有几个函数,它们具有两个可能引发错误的不同潜在区域。一个在Promise之外,另一个在内部。

async myFunction(params,payload) {

    // This function can throw an error if the database 
    // connection goes bad
    if( await this._checkExists(this.conn, params) )
        return { code: 2, message: 'Already Exists' };

    if ((await this._regCount(this.conn, params)) === 0) {
        Promise.all([
            this._sendMail(params), 
            this._notify(params),
            this._update(params)
        });

        return { code: 1, message: 'Success' };
    }
}

因为路由器是库的一部分,并且myFunction是我无法控制的用户功能,所以我希望路由器能够捕获myFunction(或任何其他函数中发生的异常)内部功能)。我不希望用户被迫在内部编写try / catch块。我希望他们使用路由器的内部错误报告功能。

使用当前的代码结构,如果我在myFunction中抛出错误,则路由器exec函数中的catch可以正常工作。但是,如果在任何内部函数(即_checkExists_sendMail)中抛出错误,等等,那么我会得到UnhandledRejection错误。

在路由器的exec函数中对此进行陷阱的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

路由器代码正常。我最终将myFunction重构为:

async myFunction(params,payload) {

    // This function can throw an error if the database 
    // connection goes bad
    if( await this._checkExists(this.conn, params) )
        return { code: 2, message: 'Already Exists' };

    if ((await this._regCount(this.conn, params)) > 0)
        return { code: 1, message: 'Already Exists' };

    Promise.all([
        this._sendMail(params), 
        this._notify(params),
        this._update(params)
    });

    return { code: 1, message: 'Success' };
}

我不确定为什么会有所作为。当然,如果在regCount中引发异常,则上面的代码将不会返回任何内容,但不确定为什么会将其冒泡为UnhandledRejection。

问题已经解决,但是异步/等待似乎很挑剔,如果您不能正确解决问题,则会在兑现承诺时遇到麻烦。

RANT:如果ECMA能够解决能够运行多线程而不是使所有工作都在单个线程中运行的核心问题,那么我们就不必经历所有这些异步痛苦。给我们线程,我们可以选择在何时何地进行同步与异步。

.... ok,从我的肥皂盒下台。

相关问题