Skip to content

Commit 40073f8

Browse files
axe312gerKyleAMathews
andauthoredJul 25, 2022
chore(gatsby-source-contentful): migrate to latest Contentful SDK (#35501)
* build: migrate to latest contentful.js * test(contenful-e2e): update snapshot version * build: clean up dependencies and update yarn.lock * fix: readd url dependency * build: upgrade to actual latest contentful js Co-authored-by: Kyle Mathews <mathews.kyle@gmail.com>

File tree

5 files changed

+104
-102
lines changed

5 files changed

+104
-102
lines changed
 

‎e2e-tests/contentful/snapshots.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/gatsby-source-contentful/package.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@
1212
"@contentful/rich-text-types": "^15.12.1",
1313
"@hapi/joi": "^15.1.1",
1414
"@vercel/fetch-retry": "^5.1.3",
15-
"axios": "^0.21.1",
1615
"chalk": "^4.1.2",
1716
"common-tags": "^1.8.2",
18-
"contentful": "^8.5.8",
17+
"contentful": "^9.1.33",
1918
"fs-extra": "^10.1.0",
2019
"gatsby-core-utils": "^3.20.0-next.0",
2120
"gatsby-plugin-utils": "^3.14.0-next.1",
@@ -24,8 +23,6 @@
2423
"json-stringify-safe": "^5.0.1",
2524
"lodash": "^4.17.21",
2625
"node-fetch": "^2.6.7",
27-
"p-queue": "^6.6.2",
28-
"retry-axios": "^2.6.0",
2926
"semver": "^7.3.7",
3027
"url": "^0.11.0"
3128
},

‎packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js

+2-32
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,11 @@ describe(`fetch-retry`, () => {
108108
const msg = expect(e.context.sourceMessage)
109109
msg.toEqual(
110110
expect.stringContaining(
111-
`Fetching contentful data failed: 500 MockedContentfulError`
111+
`Fetching contentful data failed: ERR_BAD_RESPONSE 500 MockedContentfulError`
112112
)
113113
)
114114
msg.toEqual(expect.stringContaining(`Request ID: 123abc`))
115-
msg.toEqual(
116-
expect.stringContaining(`The request was sent with 3 attempts`)
117-
)
115+
msg.toEqual(expect.stringContaining(`Attempts: 3`))
118116
}
119117
expect(reporter.panic).toBeCalled()
120118
expect(scope.isDone()).toBeTruthy()
@@ -149,34 +147,6 @@ describe(`fetch-network-errors`, () => {
149147
expect(scope.isDone()).toBeTruthy()
150148
})
151149

152-
test(`catches error with response string`, async () => {
153-
const scope = nock(baseURI)
154-
// Space
155-
.get(`/spaces/${options.spaceId}/`)
156-
.reply(502, `Bad Gateway`)
157-
158-
try {
159-
await fetchContent({
160-
pluginConfig: createPluginConfig({
161-
...options,
162-
contentfulClientConfig: { retryOnError: false },
163-
}),
164-
reporter,
165-
syncToken: null,
166-
})
167-
throw new Error(`fetchContent should throw an error`)
168-
} catch (e) {
169-
expect(e.context.sourceMessage).toEqual(
170-
expect.stringContaining(
171-
`Accessing your Contentful space failed: Bad Gateway`
172-
)
173-
)
174-
}
175-
176-
expect(reporter.panic).toBeCalled()
177-
expect(scope.isDone()).toBeTruthy()
178-
})
179-
180150
test(`catches error with response object`, async () => {
181151
const scope = nock(baseURI)
182152
// Space

‎packages/gatsby-source-contentful/src/fetch.js

+71-49
Original file line numberDiff line numberDiff line change
@@ -9,68 +9,90 @@ import { CODES } from "./report"
99
* Generate a user friendly error message.
1010
*
1111
* Contentful's API has its own error message structure, which might change depending of internal server or authentification errors.
12-
*
13-
* Additionally the SDK strips the error object, sometimes:
14-
* https://github.com/contentful/contentful.js/blob/b67b77ac8c919c4ec39203f8cac2043854ab0014/lib/create-contentful-api.js#L89-L99
15-
*
16-
* This code tries to work around this.
1712
*/
1813
const createContentfulErrorMessage = e => {
19-
if (typeof e === `string`) {
20-
return e
21-
}
22-
// If we got a response, it is very likely that it is a Contentful API error.
23-
if (e.response) {
24-
let parsedContentfulErrorData = null
14+
// Handle axios error messages
15+
if (e.isAxiosError) {
16+
const axiosErrorMessage = [e.code, e.status]
17+
const axiosErrorDetails = []
2518

26-
// Parse JSON response data, and add it to the object.
27-
if (typeof e.response.data === `string`) {
28-
try {
29-
parsedContentfulErrorData = JSON.parse(e.response.data)
30-
} catch (err) {
31-
e.message = e.response.data
19+
if (e.response) {
20+
axiosErrorMessage.push(e.response.status)
21+
22+
// Parse Contentful API error data
23+
if (e.response?.data) {
24+
axiosErrorMessage.push(e.response.data.sys?.id, e.response.data.message)
25+
}
26+
27+
// Get request ID from headers
28+
const requestId =
29+
e.response.headers &&
30+
typeof e.response.headers === `object` &&
31+
e.response.headers[`x-contentful-request-id`]
32+
33+
if (requestId) {
34+
axiosErrorDetails.push(`Request ID: ${requestId}`)
3235
}
33-
// If response data was parsed already, just add it.
34-
} else if (typeof e.response.data === `object`) {
35-
parsedContentfulErrorData = e.response.data
3636
}
3737

38-
e = { ...e, ...e.response, ...parsedContentfulErrorData }
39-
}
38+
if (e.attempts) {
39+
axiosErrorDetails.push(`Attempts: ${e.attempts}`)
40+
}
4041

41-
let errorMessage = [
42-
// Generic error values
43-
e.code && String(e.code),
44-
e.status && String(e.status),
45-
e.statusText,
46-
// Contentful API error response values
47-
e.sys?.id,
48-
]
49-
.filter(Boolean)
50-
.join(` `)
51-
52-
// Add message if it exists. Usually error default or Contentful's error message
53-
if (e.message) {
54-
errorMessage += `\n\n${e.message}`
55-
}
42+
if (axiosErrorDetails.length) {
43+
axiosErrorMessage.push(
44+
`\n\n---\n${axiosErrorDetails.join(`\n\n`)}\n\n---\n`
45+
)
46+
}
5647

57-
// Get request ID from headers or Contentful's error data
58-
const requestId =
59-
(e.headers &&
60-
typeof e.headers === `object` &&
61-
e.headers[`x-contentful-request-id`]) ||
62-
e.requestId
48+
return axiosErrorMessage.filter(Boolean).join(` `)
49+
}
6350

64-
if (requestId) {
65-
errorMessage += `\n\nRequest ID: ${requestId}`
51+
// If it is not an axios error, we assume that we got a Contentful SDK error and try to parse it
52+
const errorMessage = [e.name]
53+
const errorDetails = []
54+
try {
55+
/**
56+
* Parse stringified error data from message
57+
* https://github.com/contentful/contentful-sdk-core/blob/4cfcd452ba0752237a26ce6b79d72a50af84d84e/src/error-handler.ts#L71-L75
58+
*
59+
* @todo properly type this with TS
60+
* type {
61+
* status?: number
62+
* statusText?: string
63+
* requestId?: string
64+
* message: string
65+
* !details: Record<string, unknown>
66+
* !request?: Record<string, unknown>
67+
* }
68+
*/
69+
const errorData = JSON.parse(e.message)
70+
errorMessage.push(errorData.status && String(errorData.status))
71+
errorMessage.push(errorData.statusText)
72+
errorMessage.push(errorData.message)
73+
if (errorData.requestId) {
74+
errorDetails.push(`Request ID: ${errorData.requestId}`)
75+
}
76+
if (errorData.request) {
77+
errorDetails.push(
78+
`Request:\n${JSON.stringify(errorData.request, null, 2)}`
79+
)
80+
}
81+
if (errorData.details && Object.keys(errorData.details).length) {
82+
errorDetails.push(
83+
`Details:\n${JSON.stringify(errorData.details, null, 2)}`
84+
)
85+
}
86+
} catch (err) {
87+
// If we can't parse it, we assume its a human readable string
88+
errorMessage.push(e.message)
6689
}
6790

68-
// Tell the user about how many request attempts Contentful SDK made
69-
if (e.attempts) {
70-
errorMessage += `\n\nThe request was sent with ${e.attempts} attempts`
91+
if (errorDetails.length) {
92+
errorMessage.push(`\n\n---\n${errorDetails.join(`\n\n`)}\n\n---\n`)
7193
}
7294

73-
return errorMessage
95+
return errorMessage.filter(Boolean).join(` `)
7496
}
7597

7698
function createContentfulClientOptions({

‎yarn.lock

+29-16
Original file line numberDiff line numberDiff line change
@@ -6153,6 +6153,14 @@ axios@^0.21.1:
61536153
dependencies:
61546154
follow-redirects "^1.10.0"
61556155

6156+
axios@^0.27.0:
6157+
version "0.27.2"
6158+
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
6159+
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
6160+
dependencies:
6161+
follow-redirects "^1.14.9"
6162+
form-data "^4.0.0"
6163+
61566164
axobject-query@^2.2.0:
61576165
version "2.2.0"
61586166
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
@@ -7958,25 +7966,25 @@ contentful-resolve-response@^1.3.0:
79587966
dependencies:
79597967
fast-copy "^2.1.0"
79607968

7961-
contentful-sdk-core@^6.8.5:
7962-
version "6.10.3"
7963-
resolved "https://registry.yarnpkg.com/contentful-sdk-core/-/contentful-sdk-core-6.10.3.tgz#983fd69257c239881c43cb83e3ce9f501acfbe4a"
7964-
integrity sha512-IUBkAU1sJuVaEa2Nv1NKK5ImqpBZ5Q3EmaCFmMZx/UHKa+i98nDCSTUBOL1aJnpZ/s3AaSramsh73VQ4aK2kyA==
7969+
contentful-sdk-core@^7.0.1:
7970+
version "7.0.2"
7971+
resolved "https://registry.yarnpkg.com/contentful-sdk-core/-/contentful-sdk-core-7.0.2.tgz#5585880f546772246209de25256635ce31fd8d8e"
7972+
integrity sha512-HkBzzzJ3UGqOIJiTd4qMEMvn44ccrN7a75gEej28X1srGn05myRgJ/pWbmXJhtgpq/5gU7IURnynyKx/ecsOfg==
79657973
dependencies:
7966-
fast-copy "^2.1.0"
7974+
fast-copy "^2.1.3"
79677975
lodash.isplainobject "^4.0.6"
79687976
lodash.isstring "^4.0.1"
79697977
p-throttle "^4.1.1"
79707978
qs "^6.9.4"
79717979

7972-
contentful@^8.5.8:
7973-
version "8.5.8"
7974-
resolved "https://registry.yarnpkg.com/contentful/-/contentful-8.5.8.tgz#ad2f3549d1795310e104a6c33325352524f7bd77"
7975-
integrity sha512-6YyE95uDJYTyGKQYtqYrMzdDZe3sLkrC0UEnpXuIOeciGACRQP9ouTjRJnLMa5ONUPt0+UJh7JH3epNouPZWIw==
7980+
contentful@^9.1.33:
7981+
version "9.1.33"
7982+
resolved "https://registry.yarnpkg.com/contentful/-/contentful-9.1.33.tgz#1305254c647578ad981eae59fae1abdb07b50b6a"
7983+
integrity sha512-iiu2cC/9JvDrTK6cfSHhZ1iW6dOq+NmYMA2p5Thpv+9h2pEOyoHm1Un9Xir5XZSB11bu4POmo6JazGAn9N0tqg==
79767984
dependencies:
7977-
axios "^0.21.1"
7985+
axios "^0.27.0"
79787986
contentful-resolve-response "^1.3.0"
7979-
contentful-sdk-core "^6.8.5"
7987+
contentful-sdk-core "^7.0.1"
79807988
fast-copy "^2.1.0"
79817989
json-stringify-safe "^5.0.1"
79827990

@@ -10885,6 +10893,11 @@ fast-copy@^2.1.0:
1088510893
resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-2.1.1.tgz#f5cbcf2df64215e59b8e43f0b2caabc19848083a"
1088610894
integrity sha512-Qod3DdRgFZ8GUIM6ygeoZYpQ0QLW9cf/FS9KhhjlYggcSZXWAemAw8BOCO5LuYCrR3Uj3qXDVTUzOUwG8C7beQ==
1088710895

10896+
fast-copy@^2.1.3:
10897+
version "2.1.3"
10898+
resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-2.1.3.tgz#bf6e05ac3cb7a9d66fbf12c51dd4440e9ddd4afb"
10899+
integrity sha512-LDzYKNTHhD+XOp8wGMuCkY4eTxFZOOycmpwLBiuF3r3OjOmZnURRD8t2dUAbmKuXGbo/MGggwbSjcBdp8QT0+g==
10900+
1088810901
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
1088910902
version "3.1.3"
1089010903
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -11257,6 +11270,11 @@ follow-redirects@^1.10.0:
1125711270
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
1125811271
integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==
1125911272

11273+
follow-redirects@^1.14.9:
11274+
version "1.14.9"
11275+
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7"
11276+
integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
11277+
1126011278
font-family-papandreou@^0.2.0-patch1, font-family-papandreou@^0.2.0-patch2:
1126111279
version "0.2.0-patch2"
1126211280
resolved "https://registry.yarnpkg.com/font-family-papandreou/-/font-family-papandreou-0.2.0-patch2.tgz#c75b659e96ffbc7ab2af651cf7b4910b334e8dd2"
@@ -21815,11 +21833,6 @@ retext@^7.0.1:
2181521833
retext-stringify "^2.0.0"
2181621834
unified "^8.0.0"
2181721835

21818-
retry-axios@^2.6.0:
21819-
version "2.6.0"
21820-
resolved "https://registry.yarnpkg.com/retry-axios/-/retry-axios-2.6.0.tgz#d4dc5c8a8e73982e26a705e46a33df99a28723e0"
21821-
integrity sha512-pOLi+Gdll3JekwuFjXO3fTq+L9lzMQGcSq7M5gIjExcl3Gu1hd4XXuf5o3+LuSBsaULQH7DiNbsqPd1chVpQGQ==
21822-
2182321836
retry@0.12.0, retry@^0.12.0:
2182421837
version "0.12.0"
2182521838
resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"

0 commit comments

Comments
 (0)
Please sign in to comment.