Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Catch development store errors during init #1281

Merged
merged 3 commits into from
Aug 29, 2023
Merged
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/tall-lamps-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/cli-hydrogen': patch
---

Catch more errors during init while connecting to Shopify
42 changes: 34 additions & 8 deletions packages/cli/src/lib/graphql/admin/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import {AbortError} from '@shopify/cli-kit/node/error';
import {describe, it, expect, vi, afterEach} from 'vitest';
import {describe, it, expect, vi} from 'vitest';

import {adminRequest} from './client.js';

import {
graphqlRequest,
type GraphQLVariables,
} from '@shopify/cli-kit/node/api/graphql';
import {graphqlRequest} from '@shopify/cli-kit/node/api/graphql';

vi.mock('@shopify/cli-kit/node/api/graphql');

Expand All @@ -30,8 +27,8 @@ describe('adminRequest', () => {
expect(response).toContain(fakeResponse);
});

describe('error response', () => {
it('sends a query to the Admin API and returns an unknown error response', async () => {
describe('when there is an unknown error response', () => {
it('passes along the error message', async () => {
const fakeGraphqlError = {
errors: [
{
Expand All @@ -49,8 +46,10 @@ describe('adminRequest', () => {

await expect(response).rejects.toContain(fakeGraphqlError);
});
});

it("sends a query to the Admin API and returns an error where app isn't installed", async () => {
describe("when the app isn't installed", () => {
it('throws an AbortError', async () => {
const fakeGraphqlError = {
errors: [
{
Expand All @@ -67,6 +66,33 @@ describe('adminRequest', () => {
});

await expect(response).rejects.toThrowError(AbortError);
await expect(response).rejects.toMatch(
/Hydrogen sales channel isn\'t installed/,
);
});
});

describe("when the user doesn't have access to hydrogenStorefrontCreate", () => {
it('throws an AbortError', async () => {
const fakeGraphqlError = {
errors: [
{
message: 'Access denied for hydrogenStorefrontCreate field',
},
],
};

vi.mocked(graphqlRequest).mockRejectedValue(fakeGraphqlError);

const response = adminRequest<TestSchema>('', {
token: '',
storeFqdn: '',
});

await expect(response).rejects.toThrowError(AbortError);
await expect(response).rejects.toMatch(
/Couldn\'t connect storefront to Shopify/,
);
});
});
});
21 changes: 21 additions & 0 deletions packages/cli/src/lib/graphql/admin/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@ export async function adminRequest<T>(
);
}

if (
errors?.some?.((error) =>
error.message.includes(
'Access denied for hydrogenStorefrontCreate field',
),
)
) {
throw new AbortError("Couldn't connect storefront to Shopify", [
'Common reasons for this error include:',
{
list: {
items: [
"The Hydrogen sales channel isn't installed on the store.",
"You don't have the required account permission to manage apps or channels.",
"You're trying to connect to an ineligible store type (Trial, Development store)",
],
},
},
]);
}

throw error;
}
}