Перехват ошибок с использованием async / await для функций async и sync - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть маршрутизатор, который должен иметь возможность вызывать как асинхронные функции, так и функции синхронизации.Я установил следующий код в качестве исполнителя:

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.All, а другой - внутри.

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 маршрутизатора работает нормально.Однако, если в какой-либо из внутренних функций выдается ошибка (например, _checkExists или _sendMail) и т. Д., Я получаю ошибку UnhandledRejection.

Как правильно перехватить это вexec функция маршрутизатора?

1 Ответ

0 голосов
/ 07 февраля 2019

Код роутера в порядке.Я реструктурировал 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 просто решит основную проблему, состоящую в возможности запустить многопоточность вместо того, чтобы пытаться сделать всеработать в одном потоке, нам не пришлось бы проходить через всю эту асинхронную боль.Дайте нам потоки, и мы сможем выбрать, где и когда мы хотим синхронизировать против асинхронного.

.... ладно, ухожу из моей мыльницы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...