From 632de3e5bda069b894f685b75dfe7b2fa96779ac Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Tue, 16 Jun 2026 19:47:49 +0700 Subject: [PATCH] fix: wrap AI block in try/catch for graceful fallback when Shakespeare API fails If the AI call throws (400, 401, network error, etc.), Sasquatch now: - Catches the error silently (logs to console as warning) - Falls back to the static FAQ answer if one matches - Falls back to a friendly "try again" message if no FAQ match - Never shows a crash or blank response to the user The toolMatch reference inside the try block is properly scoped so the isLive flag works correctly when the full AI + CVM flow succeeds. Co-authored-by: shakespeare.diy --- src/components/SasquatchGuide.tsx | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/components/SasquatchGuide.tsx b/src/components/SasquatchGuide.tsx index a3bb854..b20ff39 100644 --- a/src/components/SasquatchGuide.tsx +++ b/src/components/SasquatchGuide.tsx @@ -184,9 +184,11 @@ export function SasquatchGuide({ message, onDismiss }: SasquatchGuideProps) { })); history.push({ role: 'user', content: question }); - // 3. If user is logged in, use Shakespeare AI with streaming + // 3. If user is logged in, try Shakespeare AI (with graceful fallback) if (user && shakespeare.isAuthenticated) { let accumulated = ''; + let aiSucceeded = false; + try { // First pass: get AI response which may include a TOOL: call // Prefix the system prompt into the first user message for compatibility @@ -267,13 +269,24 @@ export function SasquatchGuide({ message, onDismiss }: SasquatchGuideProps) { accumulated = aiText; } - setStreamingText(''); - appendMessage({ - role: 'sasquatch', - text: accumulated || "Hmm, couldn't process that. Try rephrasing!", - timestamp: Date.now(), - isLive: !!toolMatch && cvmConnected === true, - }); + setStreamingText(''); + appendMessage({ + role: 'sasquatch', + text: accumulated || "Hmm, couldn't process that. Try rephrasing!", + timestamp: Date.now(), + isLive: !!toolMatch && cvmConnected === true, + }); + aiSucceeded = true; + } catch (aiErr) { + // AI failed — fall back to static FAQ silently + console.warn('[Sasquatch] AI unavailable, using static FAQ:', aiErr); + } + + if (!aiSucceeded) { + const fallback = staticAnswer ?? + "Couldn't reach the AI right now. Check the map for spots, The Lab for coaches, or ask again in a moment! 🛹"; + appendMessage({ role: 'sasquatch', text: fallback, timestamp: Date.now() }); + } } else { // 6. Not logged in — use static FAQ or generic fallback