Switch request out for fetch

GitOrigin-RevId: b011976084d113c250b002c1bae23f6b38a3281c
This commit is contained in:
andrew rumble 2024-07-09 11:24:22 +01:00 committed by Copybot
parent 2ccd39b2fa
commit 709982ac65
2 changed files with 50 additions and 38 deletions

View file

@ -1,5 +1,8 @@
const OError = require('@overleaf/o-error')
const request = require('request')
const {
fetchStringWithResponse,
RequestFailedError,
} = require('@overleaf/fetch-utils')
const Settings = require('@overleaf/settings')
const xml2js = require('xml2js')
const logger = require('@overleaf/logger')
@ -378,9 +381,17 @@ const promises = {
* @param options - the options to pass to the request library
* @returns {Promise<{ response: unknown, body: string}>}
*/
apiRequest(options) {
options.url = RecurlyWrapper.apiUrl + '/' + options.url
options.headers = {
async apiRequest({ expect404, expect422, url, qs, ...fetchOptions }) {
const fetchUrl = new URL(RecurlyWrapper.apiUrl)
fetchUrl.pathname =
fetchUrl.pathname !== '/' ? `${fetchUrl.pathname}/${url}` : url
if (qs) {
for (const [key, value] of Object.entries(qs)) {
fetchUrl.searchParams.set(key, value)
}
}
fetchOptions.headers = {
Authorization: `Basic ${Buffer.from(
Settings.apis.recurly.apiKey
).toString('base64')}`,
@ -388,40 +399,36 @@ const promises = {
'Content-Type': 'application/xml; charset=utf-8',
'X-Api-Version': Settings.apis.recurly.apiVersion,
}
const { expect404, expect422 } = options
delete options.expect404
delete options.expect422
return new Promise((resolve, reject) => {
request(options, function (error, response, body) {
if (
!error &&
response.statusCode !== 200 &&
response.statusCode !== 201 &&
response.statusCode !== 204 &&
(response.statusCode !== 404 || !expect404) &&
(response.statusCode !== 422 || !expect422)
) {
if (options.headers.Authorization) {
options.headers.Authorization = 'REDACTED'
}
logger.warn(
{
err: error,
body,
options,
statusCode: response ? response.statusCode : undefined,
},
'error returned from recurly'
)
error = new OError(
`Recurly API returned with status code: ${response.statusCode}`,
{ statusCode: response.statusCode }
)
reject(error)
try {
return await fetchStringWithResponse(fetchUrl, fetchOptions)
} catch (error) {
if (error instanceof RequestFailedError) {
if (error.response.status === 404 && expect404) {
return { response: error.response, body: null }
} else if (error.response.status === 422 && expect422) {
return { response: error.response, body: error.body }
}
resolve({ response, body })
})
})
if (fetchOptions.headers.Authorization) {
fetchOptions.headers.Authorization = 'REDACTED'
}
logger.warn(
{
err: error,
body: error.body,
options: fetchOptions,
url: fetchUrl.href,
statusCode: error.response?.status,
},
'error returned from recurly'
)
throw new OError(
`Recurly API returned with status code: ${error.response.status}`,
{ statusCode: error.response.status }
)
}
}
},
async getSubscriptions(accountId) {

View file

@ -5,6 +5,7 @@ const SandboxedModule = require('sandboxed-module')
const tk = require('timekeeper')
const Errors = require('../../../../app/src/Features/Errors/Errors')
const SubscriptionErrors = require('../../../../app/src/Features/Subscription/Errors')
const { RequestFailedError } = require('@overleaf/fetch-utils')
const fixtures = {
'subscriptions/44f83d7cba354d5b84812419f923ea96':
@ -129,11 +130,15 @@ describe('RecurlyWrapper', function () {
},
}
this.fetchUtils = {
fetchStringWithResponse: sinon.stub(),
RequestFailedError,
}
tk.freeze(Date.now()) // freeze the time for these tests
this.RecurlyWrapper = SandboxedModule.require(modulePath, {
requires: {
'@overleaf/settings': this.settings,
request: sinon.stub(),
'@overleaf/fetch-utils': this.fetchUtils,
'./Errors': SubscriptionErrors,
},
})