@@ -9,6 +9,7 @@ import { X, CornerUpLeft } from "lucide-react";
99import { Header } from "@/components/ui/header" ;
1010import { SessionList } from "@/components/session/SessionList" ;
1111import { getSessionListPath } from '@/lib/navigation'
12+ import { FetchError } from '@/api/fetchWrapper'
1213
1314import { FileBrowserSheet } from "@/components/file-browser/FileBrowserSheet" ;
1415import { Dialog , DialogContent , DialogTitle } from "@/components/ui/dialog" ;
@@ -63,6 +64,18 @@ const compareMessageIds = (id1: string, id2: string): number => {
6364const PENDING_ACTION_SYNC_INTERVAL_MS = 30000
6465const PROMPT_OVERLAY_CLEARANCE_PX = 16
6566
67+ function SessionRouteFallback ( { message, backTo, backLabel } : { message : string ; backTo : string ; backLabel : string } ) {
68+ const navigate = useNavigate ( ) ;
69+ return (
70+ < div className = "flex items-center justify-center min-h-screen bg-gradient-to-br from-background via-background to-background" >
71+ < div className = "flex flex-col items-center gap-3 text-center" >
72+ < span className = "text-muted-foreground" > { message } </ span >
73+ < Button variant = "outline" size = "sm" onClick = { ( ) => navigate ( backTo ) } > { backLabel } </ Button >
74+ </ div >
75+ </ div >
76+ ) ;
77+ }
78+
6679export function SessionDetail ( ) {
6780 const { id, sessionId } = useParams < { id : string ; sessionId : string } > ( ) ;
6881 const navigate = useNavigate ( ) ;
@@ -112,6 +125,7 @@ export function SessionDetail() {
112125 queryKey : [ "repo" , repoId ] ,
113126 queryFn : ( ) => getRepo ( repoId ) ,
114127 enabled : id !== undefined ,
128+ retry : ( failureCount , error ) => ! ( error instanceof FetchError && error . statusCode === 404 ) && failureCount < 3 ,
115129 } ) ;
116130
117131 useRepoActivity ( repoId , Boolean ( repo ) ) ;
@@ -123,8 +137,8 @@ export function SessionDetail() {
123137
124138 const { isConnected, isReconnecting } = useSSE ( opcodeUrl , repoDirectory , sessionId ) ;
125139
126- const { data : rawMessages , isLoading : messagesLoading } = useMessages ( opcodeUrl , sessionId , repoDirectory ) ;
127- const { data : session , isLoading : sessionLoading } = useSession (
140+ const { data : rawMessages , isLoading : messagesLoading } = useMessages ( opcodeUrl , sessionId , repoDirectory , { fallbackPoll : ! isConnected } ) ;
141+ const { data : session , isLoading : sessionLoading , error : sessionQueryError } = useSession (
128142 opcodeUrl ,
129143 sessionId ,
130144 repoDirectory ,
@@ -408,7 +422,7 @@ export function SessionDetail() {
408422 return < Navigate to = "/" replace /> ;
409423 }
410424
411- if ( ! repo && ! isAssistantSession ) {
425+ if ( ! isAssistantSession && repoLoading ) {
412426 return (
413427 < div className = "flex items-center justify-center min-h-screen bg-gradient-to-br from-background via-background to-background" >
414428 < div className = "flex flex-col items-center gap-2" >
@@ -419,6 +433,21 @@ export function SessionDetail() {
419433 ) ;
420434 }
421435
436+ if ( ! isAssistantSession && ! repo ) {
437+ return < SessionRouteFallback message = "Repository not found" backTo = "/" backLabel = "Back to repositories" /> ;
438+ }
439+
440+ if ( sessionQueryError instanceof FetchError && sessionQueryError . statusCode === 404 ) {
441+ const listTab = new URLSearchParams ( location . search ) . get ( 'repoTab' ) ?? undefined ;
442+ return (
443+ < SessionRouteFallback
444+ message = "Session not found"
445+ backTo = { getSessionListPath ( repoId , isAssistantSession , listTab ) }
446+ backLabel = "Back to sessions"
447+ />
448+ ) ;
449+ }
450+
422451 const workspaceDisplayName = isAssistantSession || ! repo
423452 ? 'Assistant'
424453 : getRepoDisplayName ( repo ) ;
0 commit comments