Skip to content

Commit f3323c1

Browse files
Merge pull request #6263 from Shopify/app_log_errors_in_dev_output
Ensure errors in app logging render in regular dev log stream
2 parents 1cef40b + a6ae38a commit f3323c1

File tree

5 files changed

+47
-35
lines changed

5 files changed

+47
-35
lines changed

packages/app/src/cli/services/app-logs/dev/poll-app-logs.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -379,11 +379,11 @@ describe('pollAppLogs', () => {
379379
organizationId: 'organizationId',
380380
})
381381

382-
expect(outputWarnSpy).toHaveBeenCalledWith('Request throttled while polling app logs.')
382+
expect(outputWarnSpy).toHaveBeenCalledWith('Request throttled while polling app logs.', stdout)
383383
expect(vi.getTimerCount()).toEqual(1)
384384
})
385385

386-
test('displays error message, waits, and retries if error occured', async () => {
386+
test('displays error message, waits, and retries if error occurred', async () => {
387387
// Given
388388
const outputDebugSpy = vi.spyOn(output, 'outputDebug')
389389
const outputWarnSpy = vi.spyOn(output, 'outputWarn')
@@ -406,7 +406,7 @@ describe('pollAppLogs', () => {
406406
})
407407

408408
// Then
409-
expect(outputWarnSpy).toHaveBeenCalledWith('Error while polling app logs.')
409+
expect(outputWarnSpy).toHaveBeenCalledWith('Error while polling app logs.', stdout)
410410
expect(vi.getTimerCount()).toEqual(1)
411411
})
412412

@@ -450,8 +450,8 @@ describe('pollAppLogs', () => {
450450

451451
// When/Then
452452
await expect(writeAppLogsToFile).not.toHaveBeenCalled
453-
expect(outputWarnSpy).toHaveBeenCalledWith('Error while polling app logs.')
454-
expect(outputWarnSpy).toHaveBeenCalledWith('Retrying in 5 seconds.')
453+
expect(outputWarnSpy).toHaveBeenCalledWith('Error while polling app logs.', stdout)
454+
expect(outputWarnSpy).toHaveBeenCalledWith('Retrying in 5 seconds.', stdout)
455455
expect(outputDebugSpy).toHaveBeenCalledWith(expect.stringContaining('JSON'))
456456
})
457457
})

packages/app/src/cli/services/app-logs/dev/poll-app-logs.ts

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,7 @@ export const pollAppLogs = async ({
5050
const response = await developerPlatformClient.appLogs({jwtToken, cursor}, organizationId)
5151

5252
const {errors, status} = response as AppLogsError
53-
if (status !== 200) {
54-
const errorResponse = {
55-
errors: errors.map((error) => ({message: error, status})),
56-
}
57-
58-
const result = await handleFetchAppLogsError({
59-
response: errorResponse,
60-
onThrottle: (retryIntervalMs) => {
61-
outputWarn(`Request throttled while polling app logs.`)
62-
outputWarn(`Retrying in ${retryIntervalMs / 1000} seconds.`)
63-
},
64-
onUnknownError: (retryIntervalMs) => {
65-
outputWarn(`Error while polling app logs.`)
66-
outputWarn(`Retrying in ${retryIntervalMs / 1000} seconds.`)
67-
},
68-
onResubscribe: () => {
69-
return resubscribeCallback()
70-
},
71-
})
72-
73-
if (result.nextJwtToken) {
74-
nextJwtToken = result.nextJwtToken
75-
}
76-
retryIntervalMs = result.retryIntervalMs
77-
} else {
53+
if (status === 200) {
7854
const {app_logs: appLogs} = response as AppLogsSuccess
7955

8056
for (const log of appLogs) {
@@ -106,6 +82,30 @@ export const pollAppLogs = async ({
10682
)
10783
})
10884
}
85+
} else {
86+
const errorResponse = {
87+
errors: errors.map((error) => ({message: error, status})),
88+
}
89+
90+
const result = await handleFetchAppLogsError({
91+
response: errorResponse,
92+
onThrottle: (retryIntervalMs) => {
93+
outputWarn(`Request throttled while polling app logs.`, stdout)
94+
outputWarn(`Retrying in ${retryIntervalMs / 1000} seconds.`, stdout)
95+
},
96+
onUnknownError: (retryIntervalMs) => {
97+
outputWarn(`Error while polling app logs.`, stdout)
98+
outputWarn(`Retrying in ${retryIntervalMs / 1000} seconds.`, stdout)
99+
},
100+
onResubscribe: () => {
101+
return resubscribeCallback()
102+
},
103+
})
104+
105+
if (result.nextJwtToken) {
106+
nextJwtToken = result.nextJwtToken
107+
}
108+
retryIntervalMs = result.retryIntervalMs
109109
}
110110

111111
const {cursor: responseCursor} = response as AppLogsSuccess
@@ -129,8 +129,8 @@ export const pollAppLogs = async ({
129129
}, retryIntervalMs)
130130
// eslint-disable-next-line no-catch-all/no-catch-all
131131
} catch (error) {
132-
outputWarn(`Error while polling app logs.`)
133-
outputWarn(`Retrying in ${POLLING_ERROR_RETRY_INTERVAL_MS / 1000} seconds.`)
132+
outputWarn(`Error while polling app logs.`, stdout)
133+
outputWarn(`Retrying in ${POLLING_ERROR_RETRY_INTERVAL_MS / 1000} seconds.`, stdout)
134134
outputDebug(`${error as string}}\n`)
135135

136136
setTimeout(() => {

packages/app/src/cli/services/app-logs/utils.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import {outputDebug, outputWarn} from '@shopify/cli-kit/node/output'
1414
import {AbortError} from '@shopify/cli-kit/node/error'
1515
import camelcaseKeys from 'camelcase-keys'
1616
import {formatLocalDate} from '@shopify/cli-kit/common/string'
17+
import {useConcurrentOutputContext} from '@shopify/cli-kit/node/ui/components'
18+
import {Writable} from 'stream'
1719

1820
export const POLLING_INTERVAL_MS = 450
1921
export const POLLING_ERROR_RETRY_INTERVAL_MS = 5 * 1000
@@ -193,6 +195,7 @@ export const subscribeToAppLogs = async (
193195
developerPlatformClient: DeveloperPlatformClient,
194196
variables: AppLogsSubscribeMutationVariables,
195197
organizationId: string,
198+
stdout?: Writable,
196199
): Promise<string> => {
197200
// Now try the subscription with the fresh token
198201
const result = await developerPlatformClient.subscribeToAppLogs(variables, organizationId)
@@ -208,8 +211,10 @@ export const subscribeToAppLogs = async (
208211

209212
if (errors && errors.length > 0) {
210213
const errorOutput = errors.join(', ')
211-
outputWarn(`Errors subscribing to app logs: ${errorOutput}`)
212-
outputWarn('App log streaming is not available in this session.')
214+
await useConcurrentOutputContext({stripAnsi: false}, () => {
215+
outputWarn(`Errors subscribing to app logs: ${errorOutput}`, stdout)
216+
outputWarn('App log streaming is not available in this session.', stdout)
217+
})
213218
throw new AbortError(errorOutput)
214219
} else {
215220
if (!jwtToken) {

packages/app/src/cli/services/dev/processes/app-logs-polling.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ describe('app-logs-polling', () => {
142142
developerPlatformClient,
143143
appLogsSubscribeVariables,
144144
'organizationId',
145+
stdout,
145146
)
146147
expect(createLogsDir).toHaveBeenCalledWith(API_KEY)
147148
expect(pollAppLogs).toHaveBeenCalledOnce()
@@ -191,6 +192,7 @@ describe('app-logs-polling', () => {
191192
developerPlatformClient,
192193
appLogsSubscribeVariables,
193194
'organizationId',
195+
stdout,
194196
)
195197
expect(outputDebug).toHaveBeenCalledWith('Failed to start function logs: Error: uh oh, another error', stderr)
196198
expect(pollAppLogs).not.toHaveBeenCalled()

packages/app/src/cli/services/dev/processes/app-logs-polling.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ export const subscribeAndStartPolling: DevProcessFunction<SubscribeAndStartPolli
6969
{developerPlatformClient, appLogsSubscribeVariables, storeName, organizationId, appWatcher, localApp: _localApp},
7070
) => {
7171
async function startPolling(abortSignal?: AbortSignal) {
72-
const jwtToken = await subscribeToAppLogs(developerPlatformClient, appLogsSubscribeVariables, organizationId)
72+
const jwtToken = await subscribeToAppLogs(
73+
developerPlatformClient,
74+
appLogsSubscribeVariables,
75+
organizationId,
76+
stdout,
77+
)
7378

7479
const apiKey = appLogsSubscribeVariables.apiKey
7580
await createLogsDir(apiKey)

0 commit comments

Comments
 (0)