Skip to content

Commit fcbcb27

Browse files
committed
Print a more sensible error when the user's token is expired
1 parent 8007f84 commit fcbcb27

3 files changed

Lines changed: 54 additions & 0 deletions

File tree

src/cloudflare/internal/ai-api.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ export class Ai {
370370
const parsedContent = JSON.parse(content) as AiError;
371371
if (parsedContent.internalCode) {
372372
this.lastRequestInternalStatusCode = parsedContent.internalCode;
373+
373374
return new InferenceUpstreamError(
374375
`${parsedContent.internalCode}: ${parsedContent.description}`,
375376
parsedContent.name
@@ -386,6 +387,14 @@ export class Ai {
386387
return new InferenceUpstreamError(content);
387388
}
388389
} catch {
390+
// FL2 returns a plain text "error code: 1031" response when the edge
391+
// preview token has expired (e.g. during `wrangler dev`).
392+
if (content.includes('error code: 1031')) {
393+
return new InferenceUpstreamError(
394+
`${content} (your API token may have expired — try running \`wrangler login\` to obtain a fresh token)`
395+
);
396+
}
397+
389398
return new InferenceUpstreamError(content);
390399
}
391400
}

src/cloudflare/internal/test/ai/ai-api-test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,39 @@ export const tests = {
8888
assert.equal(err.message, 'Unknown error');
8989
}
9090

91+
{
92+
// Test FL2 plain text "error code: 1031" (expired preview token)
93+
// includes wrangler login hint. FL2 returns this as text/plain when
94+
// the edge preview token has expired during `wrangler dev`.
95+
const err = await env.ai._parseError(
96+
new Response('error code: 1031', {
97+
status: 400,
98+
headers: { 'content-type': 'text/plain; charset=UTF-8' },
99+
})
100+
);
101+
assert.equal(err.name, 'InferenceUpstreamError');
102+
assert.ok(err.message.includes('1031'), 'should include error code 1031');
103+
assert.ok(
104+
err.message.includes('wrangler login'),
105+
'should suggest running wrangler login'
106+
);
107+
}
108+
109+
{
110+
// Test error code 1031 via mock (expired preview token model)
111+
try {
112+
await env.ai.run('expiredTokenModel', { prompt: 'test' });
113+
assert.fail('should have thrown');
114+
} catch (e) {
115+
assert.equal(e.name, 'InferenceUpstreamError');
116+
assert.ok(e.message.includes('1031'), 'should include error code 1031');
117+
assert.ok(
118+
e.message.includes('wrangler login'),
119+
'should suggest running wrangler login'
120+
);
121+
}
122+
}
123+
91124
{
92125
// Test raw input
93126
const resp = await env.ai.run('rawInputs', { prompt: 'test' });

src/cloudflare/internal/test/ai/ai-mock.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,18 @@ export default {
126126
);
127127
}
128128

129+
if (modelName === 'expiredTokenModel') {
130+
// Simulate the real FL2 response when an edge preview token has expired.
131+
// FL2 returns plain text "error code: 1031" with HTTP 400.
132+
return new Response('error code: 1031', {
133+
status: 400,
134+
headers: {
135+
'content-type': 'text/plain; charset=UTF-8',
136+
...respHeaders,
137+
},
138+
});
139+
}
140+
129141
// Handle websocket requests
130142
if (isWebsocket && modelName === '@cf/test/websocket') {
131143
// For websocket requests, extract data from URL 'body' parameter

0 commit comments

Comments
 (0)