Skip to content

Commit 889df16

Browse files
FEAT: added helpful error responses for fetchActionPlan and fetchResources (#92)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent d32cbe8 commit 889df16

4 files changed

Lines changed: 83 additions & 13 deletions

File tree

frontend/src/app/[locale]/generate-referrals/page.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ export default function Page() {
127127
const [actionPlan, setActionPlan] = useState<ActionPlan | null>(null);
128128
const [isGeneratingActionPlan, setIsGeneratingActionPlan] = useState(false);
129129
const [activeTab, setActiveTab] = useState("find-referrals");
130+
const [errorMessage, setErrorMessage] = useState<string | undefined>(
131+
undefined,
132+
);
130133

131134
const searchParams = useSearchParams();
132135

@@ -177,14 +180,16 @@ export default function Page() {
177180

178181
setLoading(true);
179182
setResult(null);
183+
setErrorMessage(undefined);
180184
try {
181185
const request = clientDescription + getCollatedReferralOptions();
182-
const { resultId, resources } = await fetchResources(
186+
const { resultId, resources, errorMessage } = await fetchResources(
183187
request,
184188
userEmail,
185189
prompt_version_id,
186190
);
187191
setResultId(resultId);
192+
setErrorMessage(errorMessage);
188193
onResources(resources);
189194
} catch (e: unknown) {
190195
const message = e instanceof Error ? e.message : "Unknown error";
@@ -210,6 +215,7 @@ export default function Page() {
210215
setClientDescription("");
211216
setSelectedResources([]);
212217
setActionPlan(null);
218+
setErrorMessage(undefined);
213219
}
214220

215221
function handleResourceSelection(resource: Resource, checked: boolean) {
@@ -236,12 +242,20 @@ export default function Page() {
236242

237243
setIsGeneratingActionPlan(true);
238244
setActionPlan(null);
245+
setErrorMessage(undefined);
239246

240247
try {
241-
const plan = await fetchActionPlan(selectedResources, userEmail);
248+
const { actionPlan: plan, errorMessage: planError } =
249+
await fetchActionPlan(selectedResources, userEmail);
242250
setActionPlan(plan);
251+
if (planError) {
252+
setErrorMessage(planError);
253+
}
243254
} catch (error) {
244255
console.error("Error generating action plan:", error);
256+
setErrorMessage(
257+
"The server encountered an unexpected error. Please try again later.",
258+
);
245259
} finally {
246260
setIsGeneratingActionPlan(false);
247261
}
@@ -549,7 +563,10 @@ export default function Page() {
549563
{resultId && <EmailReferralsButton resultId={resultId} />}
550564
</div>
551565
</div>
552-
<ResourcesList resources={result ?? []} />
566+
<ResourcesList
567+
resources={result ?? []}
568+
errorMessage={errorMessage}
569+
/>
553570
{result && result.length > 0 && (
554571
<ActionPlanSection
555572
resources={result}

frontend/src/components/ResourcesList.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,15 @@ const normalizeUrl = (url: string) => {
5757
return `https://${trimmed}`;
5858
};
5959

60-
const ResourcesList = ({ resources }: { resources: Resource[] }) => {
60+
const ResourcesList = ({
61+
resources,
62+
errorMessage,
63+
}: {
64+
resources: Resource[];
65+
errorMessage?: string;
66+
}) => {
6167
return resources.length === 0 ? (
62-
<div className="m-3">No resources found.</div>
68+
<div className="m-3">{errorMessage || "No resources found."}</div>
6369
) : (
6470
<div className="mt-2">
6571
{resources.map((r, i) => (

frontend/src/util/fetchActionPlan.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function fixJsonControlCharacters(jsonString: string): string {
5252
export async function fetchActionPlan(
5353
resources: Resource[],
5454
userEmail: string,
55-
): Promise<ActionPlan | null> {
55+
): Promise<{ actionPlan: ActionPlan | null; errorMessage?: string }> {
5656
const apiDomain = await getApiDomain();
5757
const url = apiDomain + "generate_action_plan/run";
5858
const headers = {
@@ -78,7 +78,11 @@ export async function fetchActionPlan(
7878

7979
if (!upstream.ok) {
8080
console.error("Failed to generate action plan:", upstream.statusText);
81-
return null;
81+
return {
82+
actionPlan: null,
83+
errorMessage:
84+
"The server encountered an unexpected error. Please try again later.",
85+
};
8286
}
8387

8488
/* eslint-disable */
@@ -93,9 +97,23 @@ export async function fetchActionPlan(
9397
const actionPlan = JSON.parse(fixedJson);
9498
/* eslint-enable */
9599

96-
return actionPlan as ActionPlan;
100+
return { actionPlan: actionPlan as ActionPlan };
97101
} catch (error) {
98-
console.error("Error fetching action plan:", error);
99-
return null;
102+
clearTimeout(timer);
103+
// Check if the error is due to timeout
104+
if (error instanceof Error && error.name === "AbortError") {
105+
return {
106+
actionPlan: null,
107+
errorMessage: "Request timed out, please try again.",
108+
};
109+
}
100110
}
111+
// Generic error handling
112+
console.error("Error fetching action plan");
113+
clearTimeout(timer);
114+
return {
115+
actionPlan: null,
116+
errorMessage:
117+
"The server encountered an unexpected error. Please try again later.",
118+
};
101119
}

frontend/src/util/fetchResources.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,37 @@ export async function fetchResources(
5555

5656
/* eslint-enable */
5757

58-
return { resultId: resultUuid, resources: resourcesAsArray };
59-
} catch {
60-
return { resultId: "", resources: [] };
58+
// Check if resources array is empty
59+
if (resourcesAsArray.length === 0) {
60+
return {
61+
resultId: resultUuid,
62+
resources: [],
63+
errorMessage: "The API did not return any resource recommendations.",
64+
};
65+
}
66+
67+
// Success, return result
68+
return {
69+
resultId: resultUuid,
70+
resources: resourcesAsArray,
71+
};
72+
} catch (error) {
73+
clearTimeout(timer);
74+
// Check if the error is due to timeout
75+
if (error instanceof Error && error.name === "AbortError") {
76+
return {
77+
resultId: "",
78+
resources: [],
79+
errorMessage: "Request timed out, please try again.",
80+
};
81+
}
6182
}
83+
84+
// Generic error handling
85+
return {
86+
resultId: "",
87+
resources: [],
88+
errorMessage:
89+
"The server encountered an unexpected error. Please try again later.",
90+
};
6291
}

0 commit comments

Comments
 (0)