【问题标题】:Google JavaScript API: catching HTTP errorsGoogle JavaScript API:捕捉 HTTP 错误
【发布时间】:2016-10-15 22:52:22
【问题描述】:

AbrahamGoogle Calendar API : "Backend Error" code 503 的回答准确地描述了我的情况。在循环创建或删除日历条目的代码时,我在随机位置得到 503。

但是,我不知道如何遵循他从 Google 引用的建议,即捕获错误并使用指数回退重试交易。

下面的代码是一个循环,它将 8 个新事件放入我的日历中。它随机遇到 503 错误,这些错误是从 Google API 而不是我自己的代码抛出的。很多时候它工作没有错误。

Google API 代码在我的循环中异步运行,因此在我的循环完成之前,Google 的任何操作都不会真正执行。当异步代码抛出 503 时,我的代码周围的 try-catch 块不会触发。如果没有 try,我不能将 catch 放入回调函数中,这会缩小 catch 的范围排除 Google 的代码。

有什么建议吗?

/* Special date string format for all-day Google Calendar events.
   Time zone independent.
 */
Date.prototype.yyyy_mm_dd = function() {
    var yyyy= this.getFullYear().toString();
    var mm  = (this.getMonth()+101).toString().slice(-2); //get leading 0
    var dd  = (this.getDate()+100).toString().slice(-2);
    return yyyy+'-'+mm+'-'+dd;
}

var fastevent = {
    'summary': 'Fast',
    'organizer': {
        'self': true, 
        'displayName': 'Wes Rishel', 
        'email': 'wrishel@gmail.com'},
    'start': {'date': 'zzzz'},      // filled in for each instance
    'end': {'date': 'zzzz'},
    'colorId': '11', 
}

function addFastEvents() {
    try {
        var eventDate = calendar.getLastFastDate() || new Date;
        for (var eventCount = 0; eventCount < 8; eventCount++) {

            // advance to next Tuesday or Friday
            eventDate=eventDate.addDays(
                [2, 1, 3, 2, 1, 4, 3][eventDate.getDay()]
            );
            fastevent.start.date = eventDate.yyyy_mm_dd();
            fastevent.end.date = fastevent.start.date;
            var request = gapi.client.calendar.events.insert({
              'calendarId': 'primary',
              'resource': fastevent
            });
            request.execute(function(fastevent) {});
            calendar.getPage(eventDate); 
            calendar.setCellStyle(eventDate, 'fastingweekdaydata');
        } // for
    } catch(e) {
        p(e.message, e.name)
    }
}

【问题讨论】:

    标签: javascript google-api google-calendar-api http-error exponential-backoff


    【解决方案1】:

    指数退避是一种奇特的说法,即在每次尝试时,您都会以指数方式增加等待时间,持续一定次数后放弃请求。

    Implementing exponential backoff

    指数退避是网络的标准错误处理策略 客户端定期重试失败请求的应用程序 在越来越多的时间内。如果请求量很大或 繁重的网络流量导致服务器返回错误,指数级 退避可能是处理这些错误的好策略

    这里有一个demo code in JS,可能会给你一个想法:

    console.log = consoleLog;
    
    exponentialBackoff(sometimesFails, 10, 100, function(result) {
        console.log('the result is',result);
    });
    
    // A function that keeps trying, "toTry" until it returns true or has
    // tried "max" number of times. First retry has a delay of "delay".
    // "callback" is called upon success.
    function exponentialBackoff(toTry, max, delay, callback) {
        console.log('max',max,'next delay',delay);
        var result = toTry();
    
        if (result) {
            callback(result);
        } else {
            if (max > 0) {
                setTimeout(function() {
                    exponentialBackoff(toTry, --max, delay * 2, callback);
                }, delay);
    
            } else {
                 console.log('we give up');   
            }
        }
    }
    
    function sometimesFails() {
        var percentFail = 0.8;
    
        return Math.random() >= 0.8;
    }
    
    function consoleLog() {
        var args = [].slice.apply(arguments);
    
        document.querySelector('#result').innerHTML += '\n' + args.join(' - ');
    }
    

    【讨论】:

    • 谢谢。看来我没有很好地表达我的担忧。我了解指数备份...但由于 HTTP 调用处于惰性异步线程中,我不明白如何捕获 503。假设您在一个循环中插入十个新日历事件,并增加日期。循环线程空闲之前所有三个插入的回调函数。然后 HTTP 事件的异步线程将运行,也许其中一个会抛出 503。但我的代码无法检测到它。我尝试过 Promise 版本的 request,但令人惊讶的是,那里没有任何乐趣。
    • 我不知道如何编辑上面的评论,但我注意到了一个更正。 “所有三个插入的回调函数”应该是“所有十个插入的回调函数”
    猜你喜欢
    • 2017-09-11
    • 2014-04-18
    • 2019-10-09
    • 2010-12-05
    • 2015-08-27
    • 2013-10-12
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    相关资源
    最近更新 更多