From 4ae85da3f6b82f35b53ed6f133c4b24fc1003844 Mon Sep 17 00:00:00 2001 From: Lukas May Date: Thu, 5 Feb 2026 09:04:17 +0100 Subject: [PATCH] feat(21-04): add subscription error handling with toast feedback on all pages - Replace silent onError: () => {} with sticky toast notification - Toast uses fixed ID 'sub-error' to prevent duplicate notifications - duration: Infinity keeps toast visible until dismissed - Applied to initiatives/index.tsx, initiatives/$id.tsx, inbox.tsx --- packages/web/src/routes/inbox.tsx | 7 ++++++- packages/web/src/routes/initiatives/$id.tsx | 15 +++++++++++++-- packages/web/src/routes/initiatives/index.tsx | 8 +++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/web/src/routes/inbox.tsx b/packages/web/src/routes/inbox.tsx index e2d842c..2d884ed 100644 --- a/packages/web/src/routes/inbox.tsx +++ b/packages/web/src/routes/inbox.tsx @@ -23,7 +23,12 @@ function InboxPage() { void utils.listWaitingAgents.invalidate(); void utils.listMessages.invalidate(); }, - onError: () => {}, + onError: () => { + toast.error("Live updates disconnected. Refresh to reconnect.", { + id: "sub-error", + duration: Infinity, + }); + }, }); // Data fetching diff --git a/packages/web/src/routes/initiatives/$id.tsx b/packages/web/src/routes/initiatives/$id.tsx index da79a26..b00a2c5 100644 --- a/packages/web/src/routes/initiatives/$id.tsx +++ b/packages/web/src/routes/initiatives/$id.tsx @@ -3,6 +3,7 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { AlertCircle } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/Skeleton"; +import { toast } from "sonner"; import { trpc } from "@/lib/trpc"; import { InitiativeHeader } from "@/components/InitiativeHeader"; import { ProgressPanel } from "@/components/ProgressPanel"; @@ -218,13 +219,23 @@ function InitiativeDetailPage() { void utils.listTasks.invalidate(); void utils.listPlans.invalidate(); }, - onError: () => {}, + onError: () => { + toast.error("Live updates disconnected. Refresh to reconnect.", { + id: "sub-error", + duration: Infinity, + }); + }, }); trpc.onAgentUpdate.useSubscription(undefined, { onData: () => { void utils.listAgents.invalidate(); }, - onError: () => {}, + onError: () => { + toast.error("Live updates disconnected. Refresh to reconnect.", { + id: "sub-error", + duration: Infinity, + }); + }, }); // State diff --git a/packages/web/src/routes/initiatives/index.tsx b/packages/web/src/routes/initiatives/index.tsx index 40a1d3a..8b3d8b2 100644 --- a/packages/web/src/routes/initiatives/index.tsx +++ b/packages/web/src/routes/initiatives/index.tsx @@ -2,6 +2,7 @@ import { useState } from "react"; import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { Plus } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { toast } from "sonner"; import { trpc } from "@/lib/trpc"; import { InitiativeList } from "@/components/InitiativeList"; import { CreateInitiativeDialog } from "@/components/CreateInitiativeDialog"; @@ -31,7 +32,12 @@ function DashboardPage() { void utils.listInitiatives.invalidate(); void utils.listPhases.invalidate(); }, - onError: () => {}, + onError: () => { + toast.error("Live updates disconnected. Refresh to reconnect.", { + id: "sub-error", + duration: Infinity, + }); + }, }); return (