1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-06-15 23:00:36 +02:00

Improved fetch with retry on all three platforms

This commit is contained in:
Laurent Cozic
2017-11-12 22:52:54 +00:00
parent 71a97bd45b
commit 2cf5234e76
10 changed files with 223 additions and 125 deletions

View File

@ -5,36 +5,43 @@ const { FileApiDriverLocal } = require('lib/file-api-driver-local.js');
const { time } = require('lib/time-utils.js');
const { setLocale, defaultLocale, closestSupportedLocale } = require('lib/locale.js');
function fetchRequestCanBeRetried(error) {
if (!error) return false;
// // Node requests can go wrong is so many different ways and with so
// // many different error messages... This handler inspects the error
// // and decides whether the request can safely be repeated or not.
// function fetchRequestCanBeRetried(error) {
// if (!error) return false;
// Unfortunately the error 'Network request failed' doesn't have a type
// or error code, so hopefully that message won't change and is not localized
if (error.message == 'Network request failed') return true;
// // Unfortunately the error 'Network request failed' doesn't have a type
// // or error code, so hopefully that message won't change and is not localized
// if (error.message == 'Network request failed') return true;
// request to https://public-ch3302....1fab24cb1bd5f.md failed, reason: socket hang up"
if (error.code == 'ECONNRESET') return true;
// // request to https://public-ch3302....1fab24cb1bd5f.md failed, reason: socket hang up"
// if (error.code == 'ECONNRESET') return true;
// OneDrive (or Node?) sometimes sends back a "not found" error for resources
// that definitely exist and in this case repeating the request works.
// Error is:
// request to https://graph.microsoft.com/v1.0/drive/special/approot failed, reason: getaddrinfo ENOTFOUND graph.microsoft.com graph.microsoft.com:443
if (error.code == 'ENOTFOUND') return true;
// // OneDrive (or Node?) sometimes sends back a "not found" error for resources
// // that definitely exist and in this case repeating the request works.
// // Error is:
// // request to https://graph.microsoft.com/v1.0/drive/special/approot failed, reason: getaddrinfo ENOTFOUND graph.microsoft.com graph.microsoft.com:443
// if (error.code == 'ENOTFOUND') return true;
// network timeout at: https://public-ch3302...859f9b0e3ab.md
if (error.message && error.message.indexOf('network timeout') === 0) return true;
// // network timeout at: https://public-ch3302...859f9b0e3ab.md
// if (error.message && error.message.indexOf('network timeout') === 0) return true;
// name: 'FetchError',
// message: 'request to https://api.ipify.org/?format=json failed, reason: getaddrinfo EAI_AGAIN api.ipify.org:443',
// type: 'system',
// errno: 'EAI_AGAIN',
// code: 'EAI_AGAIN' } } reason: { FetchError: request to https://api.ipify.org/?format=json failed, reason: getaddrinfo EAI_AGAIN api.ipify.org:443
//
// It's a Microsoft error: "A temporary failure in name resolution occurred."
if (error.code == 'EAI_AGAIN') return true;
// // name: 'FetchError',
// // message: 'request to https://api.ipify.org/?format=json failed, reason: getaddrinfo EAI_AGAIN api.ipify.org:443',
// // type: 'system',
// // errno: 'EAI_AGAIN',
// // code: 'EAI_AGAIN' } } reason: { FetchError: request to https://api.ipify.org/?format=json failed, reason: getaddrinfo EAI_AGAIN api.ipify.org:443
// //
// // It's a Microsoft error: "A temporary failure in name resolution occurred."
// if (error.code == 'EAI_AGAIN') return true;
return false;
}
// // request to https://public-...8fd8bc6bb68e9c4d17a.md failed, reason: connect ETIMEDOUT 204.79.197.213:443
// // Code: ETIMEDOUT
// if (error.code === 'ETIMEDOUT') return true;
// return false;
// }
function shimInit() {
shim.fs = fs;
@ -110,31 +117,35 @@ function shimInit() {
}
shim.fetch = async function(url, options = null) {
if (!options) options = {};
if (!options.timeout) options.timeout = 1000 * 120; // ms
if (!('maxRetry' in options)) options.maxRetry = 5;
return shim.fetchWithRetry(() => {
return nodeFetch(url, options)
}, options);
let retryCount = 0;
while (true) {
try {
const response = await nodeFetch(url, options);
return response;
} catch (error) {
if (fetchRequestCanBeRetried(error)) {
retryCount++;
if (retryCount > options.maxRetry) throw error;
await time.sleep(retryCount * 3);
} else {
throw error;
}
}
}
// if (!options) options = {};
// if (!options.timeout) options.timeout = 1000 * 120; // ms
// if (!('maxRetry' in options)) options.maxRetry = 5;
// let retryCount = 0;
// while (true) {
// try {
// const response = await nodeFetch(url, options);
// return response;
// } catch (error) {
// if (fetchRequestCanBeRetried(error)) {
// retryCount++;
// if (retryCount > options.maxRetry) throw error;
// await time.sleep(retryCount * 3);
// } else {
// throw error;
// }
// }
// }
}
shim.fetchBlob = async function(url, options) {
if (!options || !options.path) throw new Error('fetchBlob: target file path is missing');
if (!options.method) options.method = 'GET';
if (!('maxRetry' in options)) options.maxRetry = 5;
//if (!('maxRetry' in options)) options.maxRetry = 5;
const urlParse = require('url').parse;
@ -192,21 +203,23 @@ function shimInit() {
});
};
let retryCount = 0;
while (true) {
try {
const response = await doFetchOperation();
return response;
} catch (error) {
if (fetchRequestCanBeRetried(error)) {
retryCount++;
if (retryCount > options.maxRetry) throw error;
await time.sleep(retryCount * 3);
} else {
throw error;
}
}
}
return shim.fetchWithRetry(doFetchOperation, options);
// let retryCount = 0;
// while (true) {
// try {
// const response = await doFetchOperation();
// return response;
// } catch (error) {
// if (fetchRequestCanBeRetried(error)) {
// retryCount++;
// if (retryCount > options.maxRetry) throw error;
// await time.sleep(retryCount * 3);
// } else {
// throw error;
// }
// }
// }
}
}