2019-10-02 07:14:21 +03:00
|
|
|
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
|
2019-10-02 07:14:21 +03:00
|
|
|
debug('StripeCardError');
|
2019-09-06 08:13:35 +03:00
|
|
|
throw err;
|
|
|
|
case 'RateLimitError':
|
|
|
|
// Ronseal
|
2019-10-02 07:14:21 +03:00
|
|
|
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':
|
2019-10-02 07:14:21 +03:00
|
|
|
debug('StripeInvalidRequestError');
|
2019-09-06 08:13:35 +03:00
|
|
|
// Invalid params to the request
|
|
|
|
throw err;
|
|
|
|
case 'StripeAPIError':
|
2019-10-02 07:14:21 +03:00
|
|
|
debug('StripeAPIError');
|
2019-09-06 08:13:35 +03:00
|
|
|
// Rare internal server error from stripe
|
|
|
|
throw err;
|
|
|
|
case 'StripeConnectionError':
|
2019-10-02 07:14:21 +03:00
|
|
|
debug('StripeConnectionError');
|
2019-09-06 08:13:35 +03:00
|
|
|
// Weird network/https issue
|
|
|
|
throw err;
|
|
|
|
case 'StripeAuthenticationError':
|
2019-10-02 07:14:21 +03:00
|
|
|
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);
|
|
|
|
}
|