Skip to content

Commit c132ab7

Browse files
committed
fix: add error handling for report fetching
Currently if fetching data fails, the UI just shows a spinner. These changes add some proper error reporting.
1 parent 074eb08 commit c132ab7

File tree

6 files changed

+57
-24
lines changed

6 files changed

+57
-24
lines changed

report-app/src/app/app.html

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,13 @@ <h1>Web Codegen Scorer</h1>
3232
alt="Loading Web Codegen Scorer Logo"
3333
class="loading-logo no-animation"
3434
/>
35-
<div>No reports available</div>
36-
<div>Run <code>web-codegen-scorer eval</code> to generate a report</div>
35+
36+
@if (groupsError()) {
37+
<pre class="callout error code">{{groupsError()}}</pre>
38+
} @else {
39+
<div>No reports available</div>
40+
<div>Run <code>web-codegen-scorer eval</code> to generate a report</div>
41+
}
3742
}
3843
</div>
3944
}

report-app/src/app/app.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class App {
1818
protected isLoading = this.reportsFetcher.isLoadingReportsList;
1919
protected isServer = isPlatformServer(inject(PLATFORM_ID));
2020
protected colorMode = this.colorModeService.colorMode;
21+
protected groupsError = this.reportsFetcher.reportGroupsError;
2122

2223
protected toggleColorMode() {
2324
this.colorModeService.setColorMode(

report-app/src/app/pages/report-viewer/report-viewer.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ <h3>Usage Details</h3>
137137

138138
@if (isLoading()) {
139139
<message-spinner message="Loading full report"/>
140+
} @else if (error()) {
141+
<pre class="callout error code">{{error()?.stack}}</pre>
140142
} @else if (report) {
141143
@let details = report.details;
142144

report-app/src/app/pages/report-viewer/report-viewer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export class ReportViewer {
7575
protected reportGroupId = input.required<string>({ alias: 'id' });
7676
protected formatted = signal<Map<LlmResponseFile, string>>(new Map());
7777
protected formatScore = formatScore;
78+
protected error = computed(() => this.selectedReport.error());
7879

7980
private selectedReport = resource({
8081
params: () => ({ groupId: this.reportGroupId() }),

report-app/src/app/services/reports-fetcher.ts

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,28 @@ export class ReportsFetcher {
1919
if (!isPlatformBrowser(this.platformId)) {
2020
return [];
2121
}
22-
return fetch('/api/reports')
23-
.then((r) => r.json() as Promise<RunGroup[]>)
24-
.then((groups) =>
25-
groups.sort((a, b) => {
26-
return (
27-
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
28-
);
29-
})
30-
);
22+
23+
const response = await fetch('/api/reports');
24+
25+
if (!response.ok) {
26+
throw new Error(`Response status: ${response.status}`);
27+
}
28+
29+
const groups = (await response.json()) as RunGroup[];
30+
31+
return groups.sort(
32+
(a, b) =>
33+
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
34+
);
3135
},
3236
});
3337

3438
readonly reportGroups = computed(() => {
3539
return this.groupsResource.hasValue() ? this.groupsResource.value() : [];
3640
});
3741

42+
readonly reportGroupsError = computed(() => this.groupsResource.error());
43+
3844
readonly isLoadingSingleReport = computed(() => this.pendingFetches() > 0);
3945
readonly isLoadingReportsList = computed(() =>
4046
this.groupsResource.isLoading()
@@ -44,19 +50,31 @@ export class ReportsFetcher {
4450
if (!this.runCache.has(groupId)) {
4551
this.pendingFetches.update((current) => current + 1);
4652

47-
const allRuns = await fetch(`/api/reports/${groupId}`).then(
48-
(r) => r.json() as Promise<RunInfo[]>
49-
);
50-
const firstRun = allRuns[0];
51-
const combined = {
52-
id: firstRun.id,
53-
group: firstRun.group,
54-
details: firstRun.details,
55-
results: allRuns.flatMap((run) => run.results),
56-
} satisfies RunInfo;
57-
58-
this.runCache.set(groupId, combined);
59-
this.pendingFetches.update((current) => current - 1);
53+
try {
54+
const response = await fetch(`/api/reports/${groupId}`);
55+
56+
if (!response.ok) {
57+
throw new Error(`Response status: ${response.status}`);
58+
}
59+
60+
const allRuns = (await response.json()) as RunInfo[];
61+
62+
if (!Array.isArray(allRuns) || allRuns.length === 0) {
63+
throw new Error(`Could not find report with id: ${groupId}`);
64+
}
65+
66+
const firstRun = allRuns[0];
67+
const combined = {
68+
id: firstRun.id,
69+
group: firstRun.group,
70+
details: firstRun.details,
71+
results: allRuns.flatMap((run) => run.results),
72+
} satisfies RunInfo;
73+
74+
this.runCache.set(groupId, combined);
75+
} finally {
76+
this.pendingFetches.update((current) => current - 1);
77+
}
6078
}
6179

6280
return this.runCache.get(groupId)!;

report-app/src/app/shared/styles/callouts.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,11 @@
2424
background-color: #fffbeb;
2525
border-color: #fef3c7;
2626
}
27+
28+
&.error {
29+
color: #cd0000;
30+
background-color: #ffe7e7;
31+
border-color: #df9e9e;
32+
}
2733
}
2834
}

0 commit comments

Comments
 (0)