Skip to content

Commit 244ea1a

Browse files
committed
return response.text from shopifyDevFetch
1 parent aa502e1 commit 244ea1a

File tree

2 files changed

+30
-52
lines changed

2 files changed

+30
-52
lines changed

src/tools/index.test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ describe("searchShopifyDocs", () => {
156156
callback("text/plain", "content-type");
157157
},
158158
},
159+
text: async () => "Internal Server Error",
159160
});
160161

161162
// Call the function directly
@@ -193,9 +194,6 @@ describe("searchShopifyDocs", () => {
193194
text: async () => "This is not valid JSON",
194195
});
195196

196-
// Clear the mocks before the test
197-
vi.mocked(console.warn).mockClear();
198-
199197
// Call the function directly
200198
const result = await searchShopifyDocs("product");
201199

@@ -204,9 +202,8 @@ describe("searchShopifyDocs", () => {
204202
expect(result.formattedText).toBe("This is not valid JSON");
205203

206204
// Verify that console.warn was called with the JSON parsing error
207-
expect(console.warn).toHaveBeenCalledTimes(1);
208-
expect(vi.mocked(console.warn).mock.calls[0][0]).toContain(
209-
"Error parsing JSON response",
205+
expect(console.warn).toHaveBeenCalledWith(
206+
expect.stringContaining("[shopify-docs] Error parsing JSON response:"),
210207
);
211208
});
212209

@@ -388,6 +385,7 @@ describe("learn_shopify_api tool behavior", () => {
388385
headers: {
389386
forEach: () => {},
390387
},
388+
text: async () => "Internal Server Error",
391389
});
392390
}
393391
return Promise.reject(new Error("Unexpected URL"));

src/tools/index.ts

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ const polarisUnifiedEnabled =
1919
* Helper function to make requests to the Shopify dev server
2020
* @param path The API path (e.g., "/mcp/search", "/mcp/getting_started")
2121
* @param options Request options including parameters and headers
22-
* @returns The fetch response
22+
* @returns The response text
23+
* @throws Error if the response is not ok
2324
*/
2425
async function shopifyDevFetch(
2526
path: string,
@@ -28,7 +29,7 @@ async function shopifyDevFetch(
2829
headers?: Record<string, string>;
2930
method?: string;
3031
},
31-
): Promise<Response> {
32+
): Promise<string> {
3233
const url = new URL(path, SHOPIFY_BASE_URL);
3334
const instrumentation = instrumentationData();
3435

@@ -69,7 +70,11 @@ async function shopifyDevFetch(
6970
`[shopify-dev] Response status: ${response.status} ${response.statusText}`,
7071
);
7172

72-
return response;
73+
if (!response.ok) {
74+
throw new Error(`HTTP error! status: ${response.status}`);
75+
}
76+
77+
return await response.text();
7378
}
7479

7580
const GettingStartedAPISchema = z.object({
@@ -102,50 +107,39 @@ const withConversationId = <T extends z.ZodRawShape>(schema: T) => ({
102107
*/
103108
export async function searchShopifyDocs(
104109
prompt: string,
105-
options?: { max_num_results?: number },
110+
max_num_results?: number,
106111
) {
107112
try {
108113
// Prepare parameters
109114
const parameters: Record<string, string> = {
110115
query: prompt,
111116
};
112117

113-
if (options?.max_num_results !== undefined) {
114-
parameters.max_num_results = String(options.max_num_results);
118+
if (max_num_results !== undefined) {
119+
parameters.max_num_results = String(max_num_results);
115120
}
116121

117-
const response = await shopifyDevFetch("/mcp/search", {
122+
const responseText = await shopifyDevFetch("/mcp/search", {
118123
parameters,
119124
});
120125

121-
if (!response.ok) {
122-
console.error(`[shopify-docs] HTTP error status: ${response.status}`);
123-
return {
124-
success: false,
125-
formattedText: `HTTP error! status: ${response.status}`,
126-
};
127-
}
128-
129-
// Read and process the response
130-
const responseText = await response.text();
131126
console.error(
132127
`[shopify-docs] Response text (truncated): ${
133128
responseText.substring(0, 200) +
134129
(responseText.length > 200 ? "..." : "")
135130
}`,
136131
);
137132

138-
// Parse and format the JSON for human readability
133+
// Try to parse and format as JSON, otherwise return raw text
139134
try {
140135
const jsonData = JSON.parse(responseText);
141136
const formattedJson = JSON.stringify(jsonData, null, 2);
142-
143137
return {
144138
success: true,
145139
formattedText: formattedJson,
146140
};
147141
} catch (e) {
148-
// If JSON parsing fails, get the raw text
142+
// If JSON parsing fails, return the raw text
149143
console.warn(`[shopify-docs] Error parsing JSON response: ${e}`);
150144
return {
151145
success: true,
@@ -217,9 +211,10 @@ export async function shopifyTools(server: McpServer): Promise<void> {
217211
),
218212
}),
219213
async (params) => {
220-
const result = await searchShopifyDocs(params.prompt, {
221-
max_num_results: params.max_num_results,
222-
});
214+
const result = await searchShopifyDocs(
215+
params.prompt,
216+
params.max_num_results,
217+
);
223218

224219
recordUsage("search_docs_chunks", params, result.formattedText).catch(
225220
() => {},
@@ -256,14 +251,12 @@ export async function shopifyTools(server: McpServer): Promise<void> {
256251
async function fetchDocText(path: string): Promise<DocResult> {
257252
try {
258253
const appendedPath = path.endsWith(".txt") ? path : `${path}.txt`;
259-
const response = await shopifyDevFetch(appendedPath);
260-
261-
if (!response.ok) {
262-
throw new Error(`HTTP error! status: ${response.status}`);
263-
}
264-
265-
const text = await response.text();
266-
return { text: `## ${path}\n\n${text}\n\n`, path, success: true };
254+
const responseText = await shopifyDevFetch(appendedPath);
255+
return {
256+
text: `## ${path}\n\n${responseText}\n\n`,
257+
path,
258+
success: true,
259+
};
267260
} catch (error) {
268261
console.error(`Error fetching document at ${path}: ${error}`);
269262
return {
@@ -385,16 +378,10 @@ export async function shopifyTools(server: McpServer): Promise<void> {
385378
}
386379

387380
try {
388-
const response = await shopifyDevFetch("/mcp/getting_started", {
381+
const responseText = await shopifyDevFetch("/mcp/getting_started", {
389382
parameters: { api: params.api },
390383
});
391384

392-
if (!response.ok) {
393-
throw new Error(`HTTP error! status: ${response.status}`);
394-
}
395-
396-
const responseText = await response.text();
397-
398385
recordUsage("learn_shopify_api", params, responseText).catch(() => {});
399386

400387
// Include the conversation ID in the response
@@ -430,15 +417,8 @@ ${responseText}`;
430417
*/
431418
async function fetchGettingStartedApis(): Promise<GettingStartedAPI[]> {
432419
try {
433-
const response = await shopifyDevFetch("/mcp/getting_started_apis");
434-
435-
if (!response.ok) {
436-
console.error(`[api-information] HTTP error status: ${response.status}`);
437-
throw new Error(`HTTP error! status: ${response.status}`);
438-
}
420+
const responseText = await shopifyDevFetch("/mcp/getting_started_apis");
439421

440-
// Read and process the response
441-
const responseText = await response.text();
442422
console.error(
443423
`[api-information] Response text (truncated): ${
444424
responseText.substring(0, 200) +

0 commit comments

Comments
 (0)