Ghost/ghost/members-api/lib/stripe/api/createStripeRequest.js

65 lines
2.2 KiB
JavaScript
Raw Normal View History

const debug = require('ghost-ignition').debug('stripe-request');
2019-09-06 08:13:35 +03:00
module.exports = function createStripeRequest(makeRequest) {
return function stripeRequest(...args) {
const errorHandler = (err) => {
switch (err.type) {
case 'StripeCardError':
// Card declined
debug('StripeCardError');
2019-09-06 08:13:35 +03:00
throw err;
case 'RateLimitError':
// Ronseal
debug('RateLimitError');
2019-09-06 08:13:35 +03:00
return exponentiallyBackoff(makeRequest, ...args).catch((err) => {
// We do not want to recurse further if we get RateLimitError
// after running the exponential backoff
if (err.type === 'RateLimitError') {
throw err;
}
return errorHandler(err);
});
case 'StripeInvalidRequestError':
debug('StripeInvalidRequestError');
2019-09-06 08:13:35 +03:00
// Invalid params to the request
throw err;
case 'StripeAPIError':
debug('StripeAPIError');
2019-09-06 08:13:35 +03:00
// Rare internal server error from stripe
throw err;
case 'StripeConnectionError':
debug('StripeConnectionError');
2019-09-06 08:13:35 +03:00
// Weird network/https issue
throw err;
case 'StripeAuthenticationError':
debug('StripeAuthenticationError');
2019-09-06 08:13:35 +03:00
// Invalid API Key (probably)
throw err;
default:
throw err;
}
};
return makeRequest(...args).catch(errorHandler);
};
};
function exponentiallyBackoff(makeRequest, ...args) {
function backoffRequest(timeout, ...args) {
return new Promise(resolve => setTimeout(resolve, timeout)).then(() => {
return makeRequest(...args).catch((err) => {
if (err.type !== 'RateLimitError') {
throw err;
}
if (timeout > 30000) {
throw err;
}
return backoffRequest(timeout * 2, ...args);
});
});
}
return backoffRequest(1000, ...args);
}