Skip to content

Commit 934980b

Browse files
committed
Fix dev-session tests
1 parent 04b045f commit 934980b

File tree

4 files changed

+65
-3
lines changed

4 files changed

+65
-3
lines changed

packages/app/src/cli/services/dev/app-events/app-event-watcher.test.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,8 @@ describe('app-event-watcher', () => {
382382
}
383383

384384
// Given
385-
const esbuildError = {message: 'Build failed'}
386-
flowExtension.buildForBundle = vi.fn().mockRejectedValueOnce(esbuildError)
385+
const buildError = {message: 'Build failed'}
386+
flowExtension.buildForBundle = vi.fn().mockRejectedValueOnce(buildError)
387387

388388
const buildOutputPath = joinPath(tmpDir, '.shopify', 'bundle')
389389
const app = testAppLinked({
@@ -406,6 +406,44 @@ describe('app-event-watcher', () => {
406406
expect(stderr.write).toHaveBeenCalledWith(`Build failed`)
407407
})
408408
})
409+
410+
test('uncaught errors are emitted', async () => {
411+
await inTemporaryDirectory(async (tmpDir) => {
412+
const fileWatchEvent: WatcherEvent = {
413+
type: 'file_updated',
414+
path: '/extensions/ui_extension_1/src/file.js',
415+
extensionPath: '/extensions/ui_extension_1',
416+
startTime: [0, 0],
417+
}
418+
419+
// Given
420+
const uncaughtError = new Error('Unexpected error')
421+
422+
const buildOutputPath = joinPath(tmpDir, '.shopify', 'bundle')
423+
const app = testAppLinked({
424+
allExtensions: [extension1],
425+
configuration: {scopes: '', extension_directories: [], path: 'shopify.app.custom.toml'},
426+
})
427+
const mockFileWatcher = new MockFileWatcher(app, outputOptions, [fileWatchEvent])
428+
429+
// When
430+
const mockManager = new MockESBuildContextManager()
431+
mockManager.updateContexts = vi.fn().mockRejectedValueOnce(uncaughtError)
432+
433+
const watcher = new AppEventWatcher(app, 'url', buildOutputPath, mockManager, mockFileWatcher)
434+
const stderr = {write: vi.fn()} as unknown as Writable
435+
const stdout = {write: vi.fn()} as unknown as Writable
436+
const errorHandler = vi.fn()
437+
watcher.onError(errorHandler)
438+
439+
await watcher.start({stdout, stderr, signal: abortController.signal})
440+
441+
await flushPromises()
442+
443+
// Then
444+
expect(errorHandler).toHaveBeenCalledWith(uncaughtError)
445+
})
446+
})
409447
})
410448
})
411449
// Mock class for ESBuildContextManager

packages/app/src/cli/services/dev/app-events/app-event-watcher.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export class AppEventWatcher extends EventEmitter {
165165
this.emit('all', appEvent)
166166
})
167167
.catch((error) => {
168-
this.options.stderr.write(`Error handling event: ${error.message}`)
168+
this.emit('error', error)
169169
})
170170
})
171171
await this.fileWatcher.start()
@@ -204,6 +204,12 @@ export class AppEventWatcher extends EventEmitter {
204204
return this
205205
}
206206

207+
onError(listener: (error: Error) => Promise<void> | void) {
208+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
209+
this.addListener('error', listener)
210+
return this
211+
}
212+
207213
/**
208214
* Deletes the build output for the given extensions.
209215
*

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ describe('pushUpdatesForDevSession', () => {
200200
expect(stdout.write).toHaveBeenCalledWith(expect.stringContaining('Action required'))
201201
expect(stdout.write).toHaveBeenCalledWith(expect.stringContaining('Scopes updated'))
202202
expect(contextSpy).toHaveBeenCalledWith({outputPrefix: 'dev-session', stripAnsi: false}, expect.anything())
203+
contextSpy.mockRestore()
203204
})
204205

205206
test('update is retried if there is an error', async () => {
@@ -273,4 +274,18 @@ describe('pushUpdatesForDevSession', () => {
273274
expect(devSessionStatus().isDevSessionReady).toBe(false)
274275
expect(devSessionStatus().devSessionPreviewURL).toBeUndefined()
275276
})
277+
278+
test('handles error events from the app watcher', async () => {
279+
// Given
280+
const testError = new Error('Watcher error')
281+
282+
// When
283+
await pushUpdatesForDevSession({stderr, stdout, abortSignal: abortController.signal}, options)
284+
appWatcher.emit('error', testError)
285+
await flushPromises()
286+
287+
// Then
288+
expect(stdout.write).toHaveBeenCalledWith(expect.stringContaining('Error'))
289+
expect(stdout.write).toHaveBeenCalledWith(expect.stringContaining('Watcher error'))
290+
})
276291
})

packages/app/src/cli/services/dev/processes/dev-session.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ export const pushUpdatesForDevSession: DevProcessFunction<DevSessionOptions> = a
166166
const result = await bundleExtensionsAndUpload({...processOptions, app: event.app})
167167
await handleDevSessionResult(result, {...processOptions, app: event.app})
168168
})
169+
.onError(async (error) => {
170+
await handleDevSessionResult({status: 'unknown-error', error}, processOptions)
171+
})
169172
}
170173

171174
async function handleDevSessionResult(

0 commit comments

Comments
 (0)