Retry API requests automatically after 5xx errors
This commit is contained in:
parent
bad9833896
commit
6d289797bf
2 changed files with 44 additions and 14 deletions
|
@ -36,6 +36,9 @@ Zotero.HTTP = new function() {
|
||||||
this.UnexpectedStatusException.prototype.is4xx = function () {
|
this.UnexpectedStatusException.prototype.is4xx = function () {
|
||||||
return this.status >= 400 && this.status < 500;
|
return this.status >= 400 && this.status < 500;
|
||||||
}
|
}
|
||||||
|
this.UnexpectedStatusException.prototype.is5xx = function () {
|
||||||
|
return this.status >= 500 && this.status < 600;
|
||||||
|
}
|
||||||
this.UnexpectedStatusException.prototype.toString = function() {
|
this.UnexpectedStatusException.prototype.toString = function() {
|
||||||
return this.message;
|
return this.message;
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,6 +37,8 @@ Zotero.Sync.APIClient = function (options) {
|
||||||
this.apiVersion = options.apiVersion;
|
this.apiVersion = options.apiVersion;
|
||||||
this.apiKey = options.apiKey;
|
this.apiKey = options.apiKey;
|
||||||
this.caller = options.caller;
|
this.caller = options.caller;
|
||||||
|
|
||||||
|
this.failureDelayIntervals = [2500, 5000, 10000, 20000, 40000, 60000, 120000, 240000, 300000];
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.Sync.APIClient.prototype = {
|
Zotero.Sync.APIClient.prototype = {
|
||||||
|
@ -437,25 +439,50 @@ Zotero.Sync.APIClient.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
makeRequest: function (method, uri, options = {}) {
|
makeRequest: Zotero.Promise.coroutine(function* (method, uri, options = {}) {
|
||||||
options.headers = this.getHeaders(options.headers);
|
options.headers = this.getHeaders(options.headers);
|
||||||
options.dontCache = true;
|
options.dontCache = true;
|
||||||
options.foreground = !options.background;
|
options.foreground = !options.background;
|
||||||
options.responseType = options.responseType || 'text';
|
options.responseType = options.responseType || 'text';
|
||||||
return this.caller.start(Zotero.Promise.coroutine(function* () {
|
var tries = 0;
|
||||||
try {
|
var failureDelayGenerator = null;
|
||||||
var xmlhttp = yield Zotero.HTTP.request(method, uri, options);
|
while (true) {
|
||||||
this._checkBackoff(xmlhttp);
|
var result = yield this.caller.start(Zotero.Promise.coroutine(function* () {
|
||||||
return xmlhttp;
|
try {
|
||||||
|
var xmlhttp = yield Zotero.HTTP.request(method, uri, options);
|
||||||
|
this._checkBackoff(xmlhttp);
|
||||||
|
return xmlhttp;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
tries++;
|
||||||
|
if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
|
||||||
|
//this._checkRetry(e.xmlhttp);
|
||||||
|
|
||||||
|
if (e.is5xx()) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
if (!failureDelayGenerator) {
|
||||||
|
// Keep trying for up to an hour
|
||||||
|
failureDelayGenerator = Zotero.Utilities.Internal.delayGenerator(
|
||||||
|
this.failureDelayIntervals, 60 * 60 * 1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let keepGoing = yield failureDelayGenerator.next();
|
||||||
|
if (!keepGoing) {
|
||||||
|
Zotero.logError("Failed too many times");
|
||||||
|
throw lastError;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}.bind(this)));
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch (e) {
|
}
|
||||||
/*if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
|
}),
|
||||||
this._checkRetry(e.xmlhttp);
|
|
||||||
}*/
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}.bind(this)));
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
_parseJSON: function (json) {
|
_parseJSON: function (json) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue