diff --git a/src/hooks/use-toast.ts b/src/hooks/use-toast.ts index bd0c9091..bc95255d 100644 --- a/src/hooks/use-toast.ts +++ b/src/hooks/use-toast.ts @@ -5,7 +5,7 @@ import * as React from "react"; import type { ToastActionElement, ToastProps } from "@/components/ui/toast"; -const TOAST_LIMIT = 1; +const TOAST_LIMIT = 3; const TOAST_REMOVE_DELAY = 1000000; type ToasterToast = ToastProps & { diff --git a/src/hooks/useChat.ts b/src/hooks/useChat.ts index 436d5178..53077790 100644 --- a/src/hooks/useChat.ts +++ b/src/hooks/useChat.ts @@ -1,6 +1,7 @@ import { useState, useEffect, useCallback, useRef } from "react"; import { useToast } from "@/hooks/use-toast"; import { supabase } from "@/utils/supabase/client"; +import * as Sentry from "@sentry/nextjs"; export interface Message { role: "user" | "assistant"; @@ -64,6 +65,7 @@ export function useChat() { }); } catch (error) { console.error("Failed to reset chat history:", error); + Sentry.captureException(error); toast({ title: "Error", description: "Failed to reset chat history.", @@ -144,6 +146,7 @@ export function useChat() { } } catch (error) { console.error("Failed to fetch history:", error); + Sentry.captureException(error); toast({ title: "Error", description: "Failed to load chat history.", @@ -233,21 +236,36 @@ export function useChat() { setIsLoading(false); } } catch (error) { + Sentry.captureException(error); console.error("Error parsing SSE data:", error); } }; - eventSource.onerror = () => { - if (isLoading) { - setIsLoading(false); - } else { - console.error("EventSource failed"); - toast({ - title: "Connection Failed", - description: "There was a problem with the connection. Please try again.", - variant: "destructive", - }); - } + eventSource.addEventListener("error", (event: MessageEvent) => { + const errorData = JSON.parse(event.data); + console.error("Received server error:", errorData.message); + + toast({ + title: "Server Error", + description: errorData.message, + variant: "destructive", + }); + + Sentry.captureException(new Error(errorData.message)); + eventSource.close(); + setIsLoading(false); + }); + + eventSource.onerror = (error: Event) => { + console.error("EventSource encountered a generic error:", error); + toast({ + title: "Connection Error", + description: "A connection error occurred. Please try again.", + variant: "destructive", + }); + + Sentry.captureException(error); + setIsLoading(false); }; eventSource.addEventListener("finish", () => { @@ -264,6 +282,7 @@ export function useChat() { }); } catch (error) { console.error("Error sending message:", error); + Sentry.captureException(error); toast({ title: "Error", description: error instanceof Error ? error.message : "Failed to send message", diff --git a/src/hooks/useCrewChat.ts b/src/hooks/useCrewChat.ts index 359daec2..df6513f8 100644 --- a/src/hooks/useCrewChat.ts +++ b/src/hooks/useCrewChat.ts @@ -1,6 +1,7 @@ import { useState, useEffect, useCallback, useRef } from "react"; import { useToast } from "@/hooks/use-toast"; import { supabase } from "@/utils/supabase/client"; +import * as Sentry from "@sentry/nextjs"; export interface Message { role: "user" | "assistant"; @@ -37,6 +38,7 @@ export function useCrewChat() { }); } catch (error) { console.error("Failed to reset chat history:", error); + Sentry.captureException(error); toast({ title: "Error", description: "Failed to reset chat history.", @@ -123,21 +125,36 @@ export function useCrewChat() { setIsLoading(false); } } catch (error) { + Sentry.captureException(error); console.error("Error parsing SSE data:", error); } }; - eventSource.onerror = () => { - if (isLoading) { - setIsLoading(false); - } else { - console.error("EventSource failed"); - toast({ - title: "Connection Failed", - description: "There was a problem with the connection. Please try again.", - variant: "destructive", - }); - } + eventSource.addEventListener("error", (event: MessageEvent) => { + const errorData = JSON.parse(event.data); + console.error("Received server error:", errorData.message); + + toast({ + title: "Server Error", + description: errorData.message, + variant: "destructive", + }); + + Sentry.captureException(new Error(errorData.message)); + eventSource.close(); + setIsLoading(false); + }); + + eventSource.onerror = (error: Event) => { + console.error("EventSource encountered a generic error:", error); + toast({ + title: "Connection Error", + description: "A connection error occurred. Please try again.", + variant: "destructive", + }); + + Sentry.captureException(error); + setIsLoading(false); }; eventSource.addEventListener("finish", () => { @@ -153,6 +170,7 @@ export function useCrewChat() { setMessages((prev) => [...prev, assistantMessage]); }); } catch (error) { + Sentry.captureException(error); console.error("Error sending message:", error); toast({ title: "Error",