mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
🐛 Fixed returning HTTP 500 response when recommendations check fails
ref ENG-737 ref https://linear.app/tryghost/issue/ENG-737/http-500-errors-from-recommendations-check-endpoint - it's still possible for `this.#externalRequest.get` to throw, like if DNS resolution fails - we want to try-catch this so we don't throw from this function and return a HTTP 500 to the user - instead, we can just return `undefined`, which is the fallback - adds a breaking test too
This commit is contained in:
parent
5fa4496d52
commit
dea639e3f6
2 changed files with 31 additions and 17 deletions
|
@ -40,25 +40,31 @@ export class RecommendationMetadataService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async #fetchJSON(url: URL, options?: {timeout?: number}) {
|
async #fetchJSON(url: URL, options?: {timeout?: number}) {
|
||||||
// default content type is application/x-www-form-encoded which is what we need for the webmentions spec
|
// Even though we have throwHttpErrors: false, we still need to catch DNS errors
|
||||||
const response = await this.#externalRequest.get(url.toString(), {
|
// that can arise from externalRequest, otherwise we'll return a HTTP 500 to the user
|
||||||
throwHttpErrors: false,
|
try {
|
||||||
maxRedirects: 10,
|
// default content type is application/x-www-form-encoded which is what we need for the webmentions spec
|
||||||
followRedirect: true,
|
const response = await this.#externalRequest.get(url.toString(), {
|
||||||
timeout: 15000,
|
throwHttpErrors: false,
|
||||||
retry: {
|
maxRedirects: 10,
|
||||||
// Only retry on network issues, or specific HTTP status codes
|
followRedirect: true,
|
||||||
limit: 3
|
timeout: 15000,
|
||||||
},
|
retry: {
|
||||||
...options
|
// Only retry on network issues, or specific HTTP status codes
|
||||||
});
|
limit: 3
|
||||||
|
},
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
|
||||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(response.body);
|
return JSON.parse(response.body);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ describe('RecommendationMetadataService', function () {
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
nock.cleanAll();
|
nock.cleanAll();
|
||||||
|
sinon.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Returns metadata from the Ghost site', async function () {
|
it('Returns metadata from the Ghost site', async function () {
|
||||||
|
@ -181,6 +182,13 @@ describe('RecommendationMetadataService', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not throw an error even if fetching throws an error', async function () {
|
||||||
|
// TODO: simulate DNS resolution failures if possible
|
||||||
|
sinon.stub(got, 'get').rejects(new Error('Failed to fetch'));
|
||||||
|
|
||||||
|
await service.fetch(new URL('https://exampleghostsite.com/subdirectory'));
|
||||||
|
});
|
||||||
|
|
||||||
it('Nullifies empty oembed data', async function () {
|
it('Nullifies empty oembed data', async function () {
|
||||||
nock('https://exampleghostsite.com')
|
nock('https://exampleghostsite.com')
|
||||||
.get('/subdirectory/members/api/site')
|
.get('/subdirectory/members/api/site')
|
||||||
|
|
Loading…
Add table
Reference in a new issue