Enhance error handling in AIEngine and update ResourceDebugOverlay

- Added error type handling in AIEngine for better error categorization during model configuration and execution.
- Updated _handle_error method to accept and log error types.
- Improved ResourceDebugOverlay to silently ignore 404 responses from the metrics endpoint, preventing unnecessary logging and retries.
- Refactored authStore to utilize fetchAPI for automatic token handling and improved error logging without throwing exceptions.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-16 11:44:51 +00:00
parent a492eb3560
commit 8908c11c86
3 changed files with 33 additions and 25 deletions

View File

@@ -215,13 +215,15 @@ class AIEngine:
except ValueError as e: except ValueError as e:
# IntegrationSettings not configured or model missing # IntegrationSettings not configured or model missing
error_msg = str(e) error_msg = str(e)
error_type = 'ConfigurationError'
logger.error(f"[AIEngine] {error_msg}") logger.error(f"[AIEngine] {error_msg}")
return self._handle_error(error_msg, fn) return self._handle_error(error_msg, fn, error_type=error_type)
except Exception as e: except Exception as e:
# Other unexpected errors # Other unexpected errors
error_msg = f"Failed to get model configuration: {str(e)}" error_msg = f"Failed to get model configuration: {str(e)}"
error_type = type(e).__name__
logger.error(f"[AIEngine] {error_msg}", exc_info=True) logger.error(f"[AIEngine] {error_msg}", exc_info=True)
return self._handle_error(error_msg, fn) return self._handle_error(error_msg, fn, error_type=error_type)
# Debug logging: Show model configuration (console only, not in step tracker) # Debug logging: Show model configuration (console only, not in step tracker)
logger.info(f"[AIEngine] Model Configuration for {function_name}:") logger.info(f"[AIEngine] Model Configuration for {function_name}:")
@@ -373,18 +375,28 @@ class AIEngine:
} }
except Exception as e: except Exception as e:
logger.error(f"Error in AIEngine.execute for {function_name}: {str(e)}", exc_info=True) error_msg = str(e)
return self._handle_error(str(e), fn, exc_info=True) error_type = type(e).__name__
logger.error(f"Error in AIEngine.execute for {function_name}: {error_msg}", exc_info=True)
return self._handle_error(error_msg, fn, exc_info=True, error_type=error_type)
def _handle_error(self, error: str, fn: BaseAIFunction = None, exc_info=False): def _handle_error(self, error: str, fn: BaseAIFunction = None, exc_info=False, error_type: str = None):
"""Centralized error handling""" """Centralized error handling"""
function_name = fn.get_name() if fn else 'unknown' function_name = fn.get_name() if fn else 'unknown'
# Determine error type
if error_type:
final_error_type = error_type
elif isinstance(error, Exception):
final_error_type = type(error).__name__
else:
final_error_type = 'Error'
self.step_tracker.add_request_step("Error", "error", error, error=error) self.step_tracker.add_request_step("Error", "error", error, error=error)
error_meta = { error_meta = {
'error': error, 'error': error,
'error_type': type(error).__name__ if isinstance(error, Exception) else 'Error', 'error_type': final_error_type,
**self.step_tracker.get_meta() **self.step_tracker.get_meta()
} }
self.tracker.error(error, meta=error_meta) self.tracker.error(error, meta=error_meta)
@@ -399,7 +411,7 @@ class AIEngine:
return { return {
'success': False, 'success': False,
'error': error, 'error': error,
'error_type': type(error).__name__ if isinstance(error, Exception) else 'Error', 'error_type': final_error_type,
'request_steps': self.step_tracker.request_steps, 'request_steps': self.step_tracker.request_steps,
'response_steps': self.step_tracker.response_steps 'response_steps': self.step_tracker.response_steps
} }

View File

@@ -128,7 +128,7 @@ export default function ResourceDebugOverlay({ enabled }: ResourceDebugOverlayPr
headers['Authorization'] = `Bearer ${token}`; headers['Authorization'] = `Bearer ${token}`;
} }
// Silently handle 404s and other errors - metrics might not exist for all requests // Silently handle 404s and other errors - metrics might not exist for all requests
try { try {
const response = await nativeFetch.call(window, `${API_BASE_URL}/v1/system/request-metrics/${requestId}/`, { const response = await nativeFetch.call(window, `${API_BASE_URL}/v1/system/request-metrics/${requestId}/`, {
method: 'GET', method: 'GET',
@@ -136,6 +136,11 @@ export default function ResourceDebugOverlay({ enabled }: ResourceDebugOverlayPr
credentials: 'include', // Include session cookies for authentication credentials: 'include', // Include session cookies for authentication
}); });
// Silently ignore 404s - metrics endpoint might not exist for all requests
if (response.status === 404) {
return; // Don't log or retry 404s
}
if (response.ok) { if (response.ok) {
const responseData = await response.json(); const responseData = await response.json();
// Extract data from unified API response format: {success: true, data: {...}} // Extract data from unified API response format: {success: true, data: {...}}

View File

@@ -192,32 +192,23 @@ export const useAuthStore = create<AuthState>()(
} }
try { try {
const API_BASE_URL = import.meta.env.VITE_BACKEND_URL || 'https://api.igny8.com/api'; // Use fetchAPI which handles token automatically and extracts data from unified format
const token = state.token || getAuthToken(); const { fetchAPI } = await import('../services/api');
const response = await fetchAPI('/v1/auth/me/');
const response = await fetch(`${API_BASE_URL}/v1/auth/me/`, { // fetchAPI extracts data field, so response is {user: {...}}
method: 'GET', if (!response || !response.user) {
headers: { throw new Error('Failed to refresh user data');
'Content-Type': 'application/json',
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
},
credentials: 'include',
});
const data = await response.json();
if (!response.ok || !data.success) {
throw new Error(data.message || 'Failed to refresh user data');
} }
// Update user data with latest from server // Update user data with latest from server
// This ensures account/plan changes are reflected immediately // This ensures account/plan changes are reflected immediately
set({ user: data.user }); set({ user: response.user });
} catch (error: any) { } catch (error: any) {
// If refresh fails, don't logout - just log the error // If refresh fails, don't logout - just log the error
// User might still be authenticated, just couldn't refresh data // User might still be authenticated, just couldn't refresh data
console.warn('Failed to refresh user data:', error); console.warn('Failed to refresh user data:', error);
throw new Error(error.message || 'Failed to refresh user data'); // Don't throw - just log the warning to prevent error accumulation
} }
}, },
}), }),