Как всегда, постарайтесь прочитать сообщение целиком, прежде чем покинуть его. Я отредактировал конец, чтобы добавить крутое обновление!

Впервые я написал в блоге о последовательностях OpenWhisk несколько месяцев назад, но если вы не читали этот пост, вы можете думать о них как об общем способе соединения нескольких различных действий вместе для формирования нового сгруппированного действия. В качестве примера, и это то, над чем я на самом деле работаю, у меня может быть действие, которое получает последние твиты от учетной записи, а также действие, которое выполняет анализ тона. Затем я могу объединить их в одну последовательность, которая вернет тон для учетной записи Twitter. (Технически мне может понадобиться третье действие посередине, чтобы массировать данные между ними.) Сегодня утром мне было немного любопытно, как ошибки обрабатываются в последовательностях. У меня были свои предположения, но я хотел проверить их, чтобы быть уверенным. Вот что я нашел.

Я начал с создания трех простых действий: альфа, бета и гамма. Вот исходники всех трех:

//Alpha
function main(args) {
    return {result:1};
}

//beta
function main(args) {
    if(!args.result) args.result=0; 
    return {result:args.result+1};
}

//gamma
function main(args) {
    if(!args.result) args.result=0; 
    return {result:args.result+1};
} 

Я назвал свою последовательность testSequence1, потому что я очень творческий человек. Затем я запустил его, чтобы убедиться, что получил правильный результат. 3. Круто.

Итак, сначала я сломал бета-версию:

function main(args) {
    if(!args.result) args.result=0; 
    doBad();
    return {result:args.result+1};
}

При запуске я получил ошибку, которую почти ожидал:

Прохладный. Итак, затем я преобразовал бета-версию для использования промисов:

function main(args) {

    return new Promise( (resolve, reject) => {
        if(!args.result) args.result=0; 
        //doBad();
        resolve({result:args.result+1});
    });
}

На этот раз я не включал ошибку, я просто убедился, что она работает, как и ожидалось, и это сработало. Прохладный. Итак, сначала я добавил обратно в свой вызов doBad:

function main(args) {

    return new Promise( (resolve, reject) => {
        if(!args.result) args.result=0; 
        doBad();
        //resolve({result:args.result+1});
    });
}

Результат был немного менее полезным:

Хотя это и не полезно, это ожидаемо. Если вы работаете с промисами и не ищете ошибку, они, как правило, проглатываются. (Я считаю, что Chrome недавно добавил поддержку обнаружения необработанных исключений, но опять же, я думаю, что это было недавнее изменение.)

Затем я переключился на эту версию:

function main(args) {

    return new Promise( (resolve, reject) => {
        if(!args.result) args.result=0; 
        //doBad();
        //resolve({result:args.result+1});
        reject(new Error("Because the sky is blue."));
    });
}

И результат был точно таким же. Я думал, что более формальное reject будет - возможно - лучше обработано, но это не так.

Но хорошая новость заключается в том, что в каждом случае, когда я проверял свою ошибку, метаданные правильно возвращали ложный результат для ключа успеха. В то время как подробность/причина ошибки были потеряны в промисе, тот факт, что ошибка была выдана, все же можно было записать.

В целом — это действительно говорит о хорошем тестировании и правильной обработке кода, который может генерировать исключения. Это относится к категории «очевидных», но как бы ни были просты OpenWhisk и бессерверные решения в целом, это абсолютно не пустая проверка, чтобы пропустить лучшие практики, когда дело доходит до обработки потенциальных ошибок.

Редактировать: И снова мой хороший приятель Carlos Santana приходит на помощь с хорошим решением. Если вы отклоняете простой объект JavaScript, а не объект Error, вы получаете лучший обработанный результат. Вот обновленный beta.js:

function main(args) {

    return new Promise( (resolve, reject) => {
        if(!args.result) args.result=0; 
        //doBad();
        //resolve({result:args.result+1});
        let e = new Error("Because the sky is blue.");
        reject({
            name:e.name,
            message: e.message,
            stack:e.stack
        });
    });
}

И вот результат:

Хороший! Использование «подобных ошибкам» ключей, конечно, произвольно. Я изменил отказ, чтобы включить howBlue:"very", и он был доступен в результате. Вероятно, имеет смысл следовать шаблону, который использовал Карлос выше, просто помните, что вы также можете добавить дополнительные элементы, если хотите.

Первоначально опубликовано на сайте www.raymondcamden.com 4 апреля 2017 г.