diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ca85eb228..72f8ea283 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2,7 +2,6 @@ import './index.css'; import React, { useEffect } from 'react'; import HomePage from './pages/HomePage'; import { BackendHealthIndicator } from './components/BackendHealthIndicator'; -import { backendService } from './services/backendService'; export default function App() { useEffect(() => { @@ -11,8 +10,9 @@ export default function App() { try { // Check if we're running in Tauri environment if (typeof window !== 'undefined' && window.__TAURI__) { + const { tauriBackendService } = await import('./services/tauriBackendService'); console.log('Running in Tauri - Starting backend on React app startup...'); - await backendService.startBackend(); + await tauriBackendService.startBackend(); console.log('Backend started successfully'); } } catch (error) { diff --git a/frontend/src/hooks/useBackendHealth.ts b/frontend/src/hooks/useBackendHealth.ts index 842175382..6a8bb84dc 100644 --- a/frontend/src/hooks/useBackendHealth.ts +++ b/frontend/src/hooks/useBackendHealth.ts @@ -1,5 +1,5 @@ import { useState, useEffect, useCallback } from 'react'; -import { backendService } from '../services/backendService'; +import { makeApiUrl } from '../utils/api'; export interface BackendHealthState { isHealthy: boolean; @@ -24,13 +24,31 @@ export const useBackendHealth = (checkInterval: number = 2000) => { setAttemptCount(prev => prev + 1); try { - const isHealthy = await backendService.checkHealth(); + // Direct HTTP call to backend health endpoint using api.ts + const healthUrl = makeApiUrl('/api/v1/info/status'); + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout + + const response = await fetch(healthUrl, { + method: 'GET', + signal: controller.signal, + headers: { + 'Accept': 'application/json', + }, + }); + + clearTimeout(timeoutId); + + const isHealthy = response.ok; + setHealthState({ isHealthy, isChecking: false, lastChecked: new Date(), error: null, }); + if (isHealthy) { setAttemptCount(0); // Reset attempt count on success } @@ -39,10 +57,19 @@ export const useBackendHealth = (checkInterval: number = 2000) => { const timeSinceStartup = now.getTime() - startupTime.getTime(); const isWithinStartupPeriod = timeSinceStartup < 60000; // 60 seconds - // Don't show error during initial startup period - const errorMessage = isWithinStartupPeriod - ? 'Backend starting up...' - : (error instanceof Error ? error.message : 'Health check failed'); + let errorMessage: string; + + if (error instanceof Error) { + if (error.name === 'AbortError') { + errorMessage = isWithinStartupPeriod ? 'Backend starting up...' : 'Health check timeout'; + } else if (error.message.includes('fetch')) { + errorMessage = isWithinStartupPeriod ? 'Backend starting up...' : 'Cannot connect to backend'; + } else { + errorMessage = isWithinStartupPeriod ? 'Backend starting up...' : error.message; + } + } else { + errorMessage = isWithinStartupPeriod ? 'Backend starting up...' : 'Health check failed'; + } setHealthState({ isHealthy: false, diff --git a/frontend/src/services/backendService.ts b/frontend/src/services/tauriBackendService.ts similarity index 77% rename from frontend/src/services/backendService.ts rename to frontend/src/services/tauriBackendService.ts index d696cfce7..79383c300 100644 --- a/frontend/src/services/backendService.ts +++ b/frontend/src/services/tauriBackendService.ts @@ -1,14 +1,14 @@ import { invoke } from '@tauri-apps/api/core'; -export class BackendService { - private static instance: BackendService; +export class TauriBackendService { + private static instance: TauriBackendService; private backendStarted = false; - static getInstance(): BackendService { - if (!BackendService.instance) { - BackendService.instance = new BackendService(); + static getInstance(): TauriBackendService { + if (!TauriBackendService.instance) { + TauriBackendService.instance = new TauriBackendService(); } - return BackendService.instance; + return TauriBackendService.instance; } async startBackend(): Promise { @@ -54,4 +54,4 @@ export class BackendService { } } -export const backendService = BackendService.getInstance(); \ No newline at end of file +export const tauriBackendService = TauriBackendService.getInstance(); \ No newline at end of file