Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/dark-mirrors-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/theme': patch
---

Command errors in the console will now include the GraphQL Request ID when present
65 changes: 65 additions & 0 deletions packages/theme/src/cli/utilities/theme-command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import {fileExistsSync} from '@shopify/cli-kit/node/fs'
import {AbortError} from '@shopify/cli-kit/node/error'
import {resolvePath} from '@shopify/cli-kit/node/path'
import {renderConcurrent, renderConfirmationPrompt, renderError, renderWarning} from '@shopify/cli-kit/node/ui'
import {getAllPublicMetadata} from '@shopify/cli-kit/node/metadata'
import type {Writable} from 'stream'

vi.mock('@shopify/cli-kit/node/session')
vi.mock('@shopify/cli-kit/node/environments')
vi.mock('@shopify/cli-kit/node/ui')
vi.mock('./theme-store.js')
vi.mock('@shopify/cli-kit/node/fs')
vi.mock('@shopify/cli-kit/node/metadata')

const CommandConfig = new Config({root: __dirname})

Expand Down Expand Up @@ -728,4 +730,67 @@ describe('ThemeCommand', () => {
expect(ensureAuthenticatedThemes).not.toHaveBeenCalled()
})
})

describe('catch', () => {
test('appends request ID to error message when available', async () => {
// Given
vi.mocked(getAllPublicMetadata).mockReturnValue({
cmd_all_last_graphql_request_id: 'test-request-id-12345',
})

await CommandConfig.load()
const command = new TestThemeCommand([], CommandConfig)
const error = new Error('Something went wrong') as Error & {skipOclifErrorHandling: boolean}
error.skipOclifErrorHandling = false

// When
await command.catch(error).catch(() => {
// Expected to throw, we just want to verify the error was modified
})

// Then
expect(error.message).toContain('Something went wrong')
expect(error.message).toContain('Request ID: test-request-id-12345')
})

test('does not append request ID when not available', async () => {
// Given
vi.mocked(getAllPublicMetadata).mockReturnValue({})

await CommandConfig.load()
const command = new TestThemeCommand([], CommandConfig)
const error = new Error('Something went wrong') as Error & {skipOclifErrorHandling: boolean}
error.skipOclifErrorHandling = false

// When
await command.catch(error).catch(() => {
// Expected to throw
})

// Then
expect(error.message).toBe('Something went wrong')
expect(error.message).not.toContain('Request ID:')
})

test('does not duplicate request ID if already present in error message', async () => {
// Given
vi.mocked(getAllPublicMetadata).mockReturnValue({
cmd_all_last_graphql_request_id: 'test-request-id-12345',
})

await CommandConfig.load()
const command = new TestThemeCommand([], CommandConfig)
const error = new Error('API error\n\nRequest ID: existing-id') as Error & {skipOclifErrorHandling: boolean}
error.skipOclifErrorHandling = false

// When
await command.catch(error).catch(() => {
// Expected to throw
})

// Then
expect(error.message).toBe('API error\n\nRequest ID: existing-id')
expect(error.message.match(/Request ID:/g)).toHaveLength(1)
})
})
})
17 changes: 16 additions & 1 deletion packages/theme/src/cli/utilities/theme-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import {AbortController} from '@shopify/cli-kit/node/abort'
import {AbortError} from '@shopify/cli-kit/node/error'
import {recordEvent, compileData} from '@shopify/cli-kit/node/analytics'
import {addPublicMetadata, addSensitiveMetadata} from '@shopify/cli-kit/node/metadata'
import {addPublicMetadata, addSensitiveMetadata, getAllPublicMetadata} from '@shopify/cli-kit/node/metadata'
import {cwd, joinPath, resolvePath} from '@shopify/cli-kit/node/path'
import {fileExistsSync} from '@shopify/cli-kit/node/fs'
import {normalizeStoreFqdn} from '@shopify/cli-kit/node/context/fqdn'
Expand Down Expand Up @@ -60,6 +60,21 @@ export default abstract class ThemeCommand extends Command {
_context?: {stdout?: Writable; stderr?: Writable},
): Promise<void> {}

async catch(error: Error & {skipOclifErrorHandling: boolean}): Promise<void> {
const metadata = getAllPublicMetadata()
const requestId = metadata.cmd_all_last_graphql_request_id

if (
requestId &&
/** Request id may have alreayd been added by `packages/cli-kit/src/private/node/api/graphql.ts` */
!error.message.includes('Request ID:')
) {
error.message += `\n\nRequest ID: ${requestId}`
}

return super.catch(error)
}

async run<
TFlags extends FlagOutput & {path?: string; verbose?: boolean},
TGlobalFlags extends FlagOutput,
Expand Down
Loading