mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Improved error log when Twitter enhanced oembed fails
ref https://linear.app/ghost/issue/ONC-506 - adding `context` with the returned API response makes the logged error much more useful as without it we only log the status code which misses any details for why the failure occurred
This commit is contained in:
parent
1d429b8b09
commit
7e50a4051f
2 changed files with 72 additions and 19 deletions
|
@ -71,6 +71,14 @@ class TwitterOEmbedProvider {
|
|||
oembedData.tweet_data = body.data;
|
||||
oembedData.tweet_data.includes = body.includes;
|
||||
} catch (err) {
|
||||
if (err.response?.body) {
|
||||
try {
|
||||
const parsed = JSON.parse(err.response.body);
|
||||
err.context = parsed;
|
||||
} catch (e) {
|
||||
err.context = err.response.body;
|
||||
}
|
||||
}
|
||||
logging.error(err);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
const assert = require('assert/strict');
|
||||
const logging = require('@tryghost/logging');
|
||||
const sinon = require('sinon');
|
||||
const TwitterOEmbedProvider = require('../../../../../core/server/services/oembed/TwitterOEmbedProvider');
|
||||
const externalRequest = require('../../../../../core/server/lib/request-external');
|
||||
const nock = require('nock');
|
||||
const {mockManager} = require('../../../../utils/e2e-framework');
|
||||
const {HTTPError} = require('got');
|
||||
|
||||
describe('TwitterOEmbedProvider', function () {
|
||||
before(async function () {
|
||||
|
@ -18,6 +21,27 @@ describe('TwitterOEmbedProvider', function () {
|
|||
mockManager.restore();
|
||||
});
|
||||
|
||||
function nockOembedRequest() {
|
||||
nock('https://publish.twitter.com')
|
||||
.get('/oembed')
|
||||
.query(true)
|
||||
.reply(200, {
|
||||
data: {
|
||||
conversation_id: '1630581157568839683',
|
||||
public_metrics: {
|
||||
retweet_count: 6,
|
||||
reply_count: 1,
|
||||
like_count: 27
|
||||
}
|
||||
},
|
||||
includes: {
|
||||
verified: false,
|
||||
description: 'some description',
|
||||
location: 'someplace, somewhere'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
it('Can support requests for Twitter URLs', async function () {
|
||||
const provider = new TwitterOEmbedProvider();
|
||||
const tweetURL = new URL(
|
||||
|
@ -48,26 +72,10 @@ describe('TwitterOEmbedProvider', function () {
|
|||
'https://twitter.com/Ghost/status/1630581157568839683'
|
||||
);
|
||||
|
||||
// not certain why we hit publish.twitter.com
|
||||
nock('https://publish.twitter.com')
|
||||
.get('/oembed')
|
||||
.query(true)
|
||||
.reply(200, {
|
||||
data: {
|
||||
conversation_id: '1630581157568839683',
|
||||
public_metrics: {
|
||||
retweet_count: 6,
|
||||
reply_count: 1,
|
||||
like_count: 27
|
||||
}
|
||||
},
|
||||
includes: {
|
||||
verified: false,
|
||||
description: 'some description',
|
||||
location: 'someplace, somewhere'
|
||||
}
|
||||
});
|
||||
// oembed-extractor first fetches the main oembed data
|
||||
nockOembedRequest();
|
||||
|
||||
// then we fetch additional data from the Twitter API
|
||||
nock('https://api.twitter.com')
|
||||
.get('/2/tweets/1630581157568839683')
|
||||
.query(true)
|
||||
|
@ -93,4 +101,41 @@ describe('TwitterOEmbedProvider', function () {
|
|||
assert.ok(oembedData.data);
|
||||
assert.ok(oembedData.includes);
|
||||
});
|
||||
|
||||
it('logs error with context when external request fails', async function () {
|
||||
const provider = new TwitterOEmbedProvider({
|
||||
config: {
|
||||
bearerToken: 'test'
|
||||
}
|
||||
});
|
||||
const tweetURL = new URL(
|
||||
'https://twitter.com/Ghost/status/1630581157568839683'
|
||||
);
|
||||
|
||||
nockOembedRequest();
|
||||
|
||||
nock('https://api.twitter.com')
|
||||
.get('/2/tweets/1630581157568839683')
|
||||
.query(true)
|
||||
.reply(403, {
|
||||
client_id: '12345',
|
||||
detail: 'Testing requests are forbidden!',
|
||||
reason: 'thou-shalt-not-pass'
|
||||
});
|
||||
|
||||
const loggingStub = sinon.stub(logging, 'error');
|
||||
|
||||
await provider.getOEmbedData(tweetURL, externalRequest);
|
||||
|
||||
sinon.assert.calledOnce(loggingStub);
|
||||
sinon.assert.calledWithMatch(loggingStub,
|
||||
sinon.match.instanceOf(HTTPError).and(
|
||||
sinon.match.has('context', {
|
||||
client_id: '12345',
|
||||
detail: 'Testing requests are forbidden!',
|
||||
reason: 'thou-shalt-not-pass'
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue