Skip to content

Commit 20c7359

Browse files
fix: fail build when extension failed to be retrieved (#5915)
* fix: fail build when extension failed to be retrieved * fix(config): fail build if fetching extensions returns a non 200 response * fix(config): update snapshot * chore: refactor * chore: merge with main * fix: reset package-lock.json to match origin/main
1 parent 7e99c26 commit 20c7359

File tree

4 files changed

+42
-8
lines changed

4 files changed

+42
-8
lines changed

packages/config/src/api/site_info.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ const getIntegrations = async function ({
116116
accountId,
117117
testOpts,
118118
offline,
119-
}: GetIntegrationsOpts): Promise<IntegrationResponse[]> {
119+
}: GetIntegrationsOpts): Promise<IntegrationResponse[] | undefined> {
120120
if (!siteId || offline) {
121121
return []
122122
}
@@ -130,15 +130,21 @@ const getIntegrations = async function ({
130130
? `${baseUrl}team/${accountId}/integrations/installations/meta/${siteId}`
131131
: `${baseUrl}site/${siteId}/integrations/safe`
132132

133+
let response
133134
try {
134-
const response = await fetch(url)
135+
response = await fetch(url)
136+
if (response.status !== 200) {
137+
throw new Error(`Unexpected status code ${response.status} from fetching extensions`)
138+
}
139+
} catch (error) {
140+
throwUserError(`Failed retrieving extensions for site ${siteId}: ${error.message}. ${ERROR_CALL_TO_ACTION}`)
141+
}
135142

136-
const integrations = await response.json()
137-
return Array.isArray(integrations) ? integrations : []
143+
try {
144+
if (Number(response.headers.get(`content-length`)) === 0) return []
145+
const responseBody = await response.json()
146+
return Array.isArray(responseBody) ? responseBody : []
138147
} catch (error) {
139-
// Integrations should not block the build if they fail to load
140-
// TODO: We should consider blocking the build as integrations are a critical part of the build process
141-
// https://linear.app/netlify/issue/CT-1214/implement-strategy-in-builds-to-deal-with-integrations-that-we-fail-to
142-
return []
148+
throwUserError(`Failed to parse extensions for site ${siteId}: ${error.message}. ${ERROR_CALL_TO_ACTION}`)
143149
}
144150
}

packages/config/tests/api/snapshots/tests.js.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,6 +2250,12 @@ Generated by [AVA](https://avajs.dev).
22502250
"token": "test"␊
22512251
}`
22522252

2253+
## Integrations teamintegrationsInstallationsMeta API error
2254+
2255+
> Snapshot 1
2256+
2257+
'Failed retrieving extensions for site test: Unexpected status code 500 from fetching extensions. Double-check your login status with \'netlify status\' or contact support with details of your error.'
2258+
22532259
## baseRelDir is true if build.base is overridden
22542260

22552261
> Snapshot 1
49 Bytes
Binary file not shown.

packages/config/tests/api/tests.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ const TEAM_INSTALLATIONS_META_RESPONSE = {
3737
],
3838
}
3939

40+
const TEAM_INSTALLATIONS_META_RESPONSE_ERROR = {
41+
path: '/team/account1/integrations/installations/meta/test',
42+
response: { error: 'Internal Server Error' },
43+
status: 500,
44+
}
45+
4046
const SITE_INTEGRATIONS_EMPTY_RESPONSE = {
4147
path: '/site/test/integrations/safe',
4248
response: [],
@@ -413,6 +419,22 @@ test('Integrations are returned if accountId is present and mode is dev', async
413419
t.assert(config.integrations[0].has_build === true)
414420
})
415421

422+
test('Integrations teamintegrationsInstallationsMeta API error', async (t) => {
423+
const { output } = await new Fixture('./fixtures/base')
424+
.withFlags({
425+
siteId: 'test',
426+
mode: 'buildbot',
427+
token: 'test',
428+
accountId: 'account1',
429+
featureFlags: {
430+
cli_integration_installations_meta: true,
431+
},
432+
})
433+
.runConfigServer([SITE_INFO_DATA, TEAM_INSTALLATIONS_META_RESPONSE_ERROR, FETCH_INTEGRATIONS_EMPTY_RESPONSE])
434+
435+
t.snapshot(normalizeOutput(output))
436+
})
437+
416438
test('baseRelDir is true if build.base is overridden', async (t) => {
417439
const fixturesDir = normalize(`${fileURLToPath(test.meta.file)}/../fixtures`)
418440

0 commit comments

Comments
 (0)