Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e01516d

Browse filesBrowse files
authored
fix: if the purge api call fails, include the api response body in the thrown error's message (#571)
1 parent bb1fb1c commit e01516d
Copy full SHA for e01516d

File tree

Expand file treeCollapse file tree

3 files changed

+69
-13
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+69
-13
lines changed

‎.eslintrc.js

Copy file name to clipboardExpand all lines: .eslintrc.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module.exports = {
66
extends: '@netlify/eslint-config-node',
77
rules: {
88
'max-statements': 'off',
9+
'max-lines': 'off',
910
},
1011
overrides: [
1112
...overrides,

‎src/lib/purge_cache.test.ts

Copy file name to clipboardExpand all lines: src/lib/purge_cache.test.ts
+46-4Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@ test('Calls the purge API endpoint and returns `undefined` if the operation was
5858
expect(mockAPI.fulfilled).toBeTruthy()
5959
})
6060

61-
test('Throws if the API response does not have a successful status code', async () => {
61+
test('Throws an error if the API response does not have a successful status code, using the response body as part of the error message', async () => {
6262
if (!hasFetchAPI) {
6363
console.warn('Skipping test requires the fetch API')
64+
65+
return
6466
}
6567

6668
const mockSiteID = '123456789'
@@ -77,7 +79,7 @@ test('Throws if the API response does not have a successful status code', async
7779
},
7880
headers: { Authorization: `Bearer ${mockToken}` },
7981
method: 'post',
80-
response: new Response(null, { status: 500 }),
82+
response: new Response('site not found', { status: 404 }),
8183
url: `https://api.netlify.com/api/v1/purge`,
8284
})
8385
// eslint-disable-next-line unicorn/consistent-function-scoping
@@ -90,14 +92,54 @@ test('Throws if the API response does not have a successful status code', async
9092
try {
9193
await invokeLambda(myFunction)
9294

93-
throw new Error('Invocation should have failed')
95+
expect.fail('Invocation should have failed')
9496
} catch (error) {
9597
expect((error as NodeJS.ErrnoException).message).toBe(
96-
'Cache purge API call returned an unexpected status code: 500',
98+
'Cache purge API call was unsuccessful.\nStatus: 404\nBody: site not found',
9799
)
98100
}
99101
})
100102

103+
test('Throws if the API response does not have a successful status code, does not include the response body if it is not text', async () => {
104+
if (!hasFetchAPI) {
105+
console.warn('Skipping test requires the fetch API')
106+
107+
return
108+
}
109+
110+
const mockSiteID = '123456789'
111+
const mockToken = '1q2w3e4r5t6y7u8i9o0p'
112+
113+
process.env.NETLIFY_PURGE_API_TOKEN = mockToken
114+
process.env.SITE_ID = mockSiteID
115+
116+
const mockAPI = new MockFetch().post({
117+
body: (payload: string) => {
118+
const data = JSON.parse(payload)
119+
120+
expect(data.site_id).toBe(mockSiteID)
121+
},
122+
headers: { Authorization: `Bearer ${mockToken}` },
123+
method: 'post',
124+
response: new Response(null, { status: 500 }),
125+
url: `https://api.netlify.com/api/v1/purge`,
126+
})
127+
// eslint-disable-next-line unicorn/consistent-function-scoping
128+
const myFunction = async () => {
129+
await purgeCache()
130+
}
131+
132+
globalThis.fetch = mockAPI.fetcher
133+
134+
try {
135+
await invokeLambda(myFunction)
136+
137+
throw new Error('Invocation should have failed')
138+
} catch (error) {
139+
expect((error as NodeJS.ErrnoException).message).toBe('Cache purge API call was unsuccessful.\nStatus: 500')
140+
}
141+
})
142+
101143
test('Ignores purgeCache if in local dev with no token or site', async () => {
102144
if (!hasFetchAPI) {
103145
console.warn('Skipping test requires the fetch API')

‎src/lib/purge_cache.ts

Copy file name to clipboardExpand all lines: src/lib/purge_cache.ts
+22-9Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ export const purgeCache = async (options: PurgeCacheOptions = {}) => {
3838
)
3939
}
4040

41+
const { siteID } = options as PurgeCacheOptionsWithSiteID
42+
const { siteSlug } = options as PurgeCacheOptionsWithSiteSlug
43+
const { domain } = options as PurgeCacheOptionsWithDomain
44+
45+
if ((siteID && siteSlug) || (siteID && domain) || (siteSlug && domain)) {
46+
throw new Error('Can only pass one of either "siteID", "siteSlug", or "domain"')
47+
}
48+
4149
const payload: PurgeAPIPayload = {
4250
cache_tags: options.tags,
4351
deploy_alias: options.deployAlias,
@@ -50,22 +58,20 @@ export const purgeCache = async (options: PurgeCacheOptions = {}) => {
5058
return
5159
}
5260

53-
if ('siteSlug' in options) {
54-
payload.site_slug = options.siteSlug
55-
} else if ('domain' in options) {
56-
payload.domain = options.domain
61+
if (siteSlug) {
62+
payload.site_slug = siteSlug
63+
} else if (domain) {
64+
payload.domain = domain
5765
} else {
5866
// The `siteID` from `options` takes precedence over the one from the
5967
// environment.
60-
const siteID = options.siteID || env.SITE_ID
68+
payload.site_id = siteID || env.SITE_ID
6169

62-
if (!siteID) {
70+
if (!payload.site_id) {
6371
throw new Error(
6472
'The Netlify site ID was not found in the execution environment. Please supply it manually using the `siteID` property.',
6573
)
6674
}
67-
68-
payload.site_id = siteID
6975
}
7076

7177
if (!token) {
@@ -91,6 +97,13 @@ export const purgeCache = async (options: PurgeCacheOptions = {}) => {
9197
})
9298

9399
if (!response.ok) {
94-
throw new Error(`Cache purge API call returned an unexpected status code: ${response.status}`)
100+
let text
101+
try {
102+
text = await response.text()
103+
} catch {}
104+
if (text) {
105+
throw new Error(`Cache purge API call was unsuccessful.\nStatus: ${response.status}\nBody: ${text}`)
106+
}
107+
throw new Error(`Cache purge API call was unsuccessful.\nStatus: ${response.status}`)
95108
}
96109
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.