Skip to content

Commit 5e0e34c

Browse files
wolfibDevtools-frontend LUCI CQ
authored andcommitted
[Console Insights] Handle timeout of the doConversation API
Show informative message to the user when the doConversation API times out. Screencast: https://i.imgur.com/UUbBuf1.mp4 (with artificially short timeout of 2s) Bug: 385122375 Change-Id: I9a51fe3d63f0018bbe0a102e65c0516551dd20c5 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6197942 Auto-Submit: Wolfgang Beyer <[email protected]> Reviewed-by: Alex Rudenko <[email protected]> Commit-Queue: Alex Rudenko <[email protected]>
1 parent 5742bac commit 5e0e34c

File tree

5 files changed

+62
-4
lines changed

5 files changed

+62
-4
lines changed

front_end/core/host/AidaClient.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,19 @@ describeWithEnvironment('AidaClient', () => {
412412
}
413413
});
414414

415+
it('throws a timeout error on timeout', async () => {
416+
sinon.stub(Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'doAidaConversation').callsArgWith(2, {
417+
netErrorName: 'net::ERR_TIMED_OUT'
418+
});
419+
const provider = new Host.AidaClient.AidaClient();
420+
try {
421+
await getAllResults(provider);
422+
expect.fail('provider.fetch did not throw');
423+
} catch (err) {
424+
expect(err.message).equals('doAidaConversation timed out');
425+
}
426+
});
427+
415428
it('throws an error for other codes', async () => {
416429
sinon.stub(Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'doAidaConversation').callsArgWith(2, {
417430
statusCode: 418,

front_end/core/host/AidaClient.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ export class AidaClient {
337337
stream.fail(new Error('Server responded: permission denied'));
338338
} else if (result.error) {
339339
stream.fail(new Error(`Cannot send request: ${result.error} ${result.detail || ''}`));
340+
} else if (result.netErrorName === 'net::ERR_TIMED_OUT') {
341+
stream.fail(new Error('doAidaConversation timed out'));
340342
} else if (result.statusCode !== 200) {
341343
stream.fail(new Error(`Request failed: ${JSON.stringify(result)}`));
342344
} else {

front_end/panels/explain/components/ConsoleInsight.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,34 @@ describeWithEnvironment('ConsoleInsight', () => {
162162
assert(component.shadowRoot!.querySelector('.rating'));
163163
});
164164

165+
it('shows an error message on timeout', async () => {
166+
function getAidaClientWithTimeout() {
167+
return {
168+
async *
169+
fetch() {
170+
yield {
171+
explanation: 'test',
172+
metadata: {
173+
rpcGlobalId: 0,
174+
},
175+
completed: true,
176+
};
177+
throw new Error('doAidaConversation timed out');
178+
},
179+
registerClientEvent: sinon.spy(),
180+
};
181+
}
182+
183+
component = new Explain.ConsoleInsight(
184+
getTestPromptBuilder(), getAidaClientWithTimeout(), Host.AidaClient.AidaAccessPreconditions.AVAILABLE);
185+
renderElementIntoDOM(component);
186+
await drainMicroTasks();
187+
assert.isNotNull(component.shadowRoot);
188+
assert.strictEqual(
189+
component.shadowRoot.querySelector('.error-message')?.textContent,
190+
'Generating a response took too long. Please try again.');
191+
});
192+
165193
const reportsRating = (positive: boolean) => async () => {
166194
const stub = getGetHostConfigStub({});
167195
const actionTaken = sinon.stub(Host.userMetrics, 'actionTaken');

front_end/panels/explain/components/ConsoleInsight.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ const UIStrings = {
139139
* @description Sub-heading for a list of links to URLs which are related to the AI-generated response.
140140
*/
141141
relatedContent: 'Related content',
142+
/**
143+
* @description Error message shown when the request to get an AI response times out.
144+
*/
145+
timedOut: 'Generating a response took too long. Please try again.',
142146
};
143147
const str_ = i18n.i18n.registerUIStrings('panels/explain/components/ConsoleInsight.ts', UIStrings);
144148
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -200,6 +204,7 @@ type StateData = {
200204
completed: boolean,
201205
directCitationUrls: string[],
202206
highlightIndex?: number,
207+
timedOut?: boolean,
203208
}&Host.AidaClient.AidaResponse|{
204209
type: State.ERROR,
205210
error: string,
@@ -564,10 +569,15 @@ export class ConsoleInsight extends HTMLElement {
564569
Host.userMetrics.actionTaken(Host.UserMetrics.Action.InsightGenerated);
565570
} catch (err) {
566571
Host.userMetrics.actionTaken(Host.UserMetrics.Action.InsightErrored);
567-
this.#transitionTo({
568-
type: State.ERROR,
569-
error: err.message,
570-
});
572+
if (err.message === 'doAidaConversation timed out' && this.#state.type === State.INSIGHT) {
573+
this.#state.timedOut = true;
574+
this.#transitionTo({...this.#state, completed: true, timedOut: true});
575+
} else {
576+
this.#transitionTo({
577+
type: State.ERROR,
578+
error: err.message,
579+
});
580+
}
571581
}
572582
}
573583

@@ -763,6 +773,7 @@ export class ConsoleInsight extends HTMLElement {
763773
.data=${{tokens: this.#state.tokens, renderer: this.#renderer, animationEnabled: true} as MarkdownView.MarkdownView.MarkdownViewData}>
764774
</devtools-markdown-view>`: this.#state.explanation
765775
}
776+
${this.#state.timedOut ? html`<p class="error-message">${i18nString(UIStrings.timedOut)}</p>` : LitHtml.nothing}
766777
${this.#isSearchRagResponse(this.#state.metadata) ? html`
767778
<details class="references" ${LitHtml.Directives.ref(this.#referenceDetailsRef)} @toggle=${this.#onToggleReferenceDetails} jslog=${VisualLogging.expand('references').track({click: true})}>
768779
<summary>${i18nString(UIStrings.references)}</summary>

front_end/panels/explain/components/consoleInsight.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,7 @@ details h3 {
383383
color: var(--sys-color-on-surface-subtle);
384384
padding-left: var(--sys-size-6);
385385
}
386+
387+
.error-message {
388+
font: var(--sys-typescale-body4-bold);
389+
}

0 commit comments

Comments
 (0)