From 95c25ccb78feaa539c4b585fde912f428fdf2117 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Fri, 14 Mar 2025 11:58:03 -0700 Subject: [PATCH] docs working test error display --- .../add_model/ConnectionErrorDisplay.tsx | 56 +++++++++++++++++++ .../src/components/networking.tsx | 46 +++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 ui/litellm-dashboard/src/components/add_model/ConnectionErrorDisplay.tsx diff --git a/ui/litellm-dashboard/src/components/add_model/ConnectionErrorDisplay.tsx b/ui/litellm-dashboard/src/components/add_model/ConnectionErrorDisplay.tsx new file mode 100644 index 00000000000..de3a057c329 --- /dev/null +++ b/ui/litellm-dashboard/src/components/add_model/ConnectionErrorDisplay.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { Typography, Space, Button, Divider } from 'antd'; +import { WarningOutlined, InfoCircleOutlined } from '@ant-design/icons'; +import { ErrorViewer } from '../view_logs/ErrorViewer'; + +const { Text } = Typography; + +interface ConnectionErrorDisplayProps { + error: Error | string; + modelName?: string; + onClose?: () => void; +} + +const ConnectionErrorDisplay: React.FC = ({ + error, + modelName = "this model", + onClose +}) => { + const errorMessage = typeof error === 'string' ? error : error.message; + + // Create an error info object compatible with ErrorViewer + const errorInfo = { + error_message: errorMessage.split('\n')[0], + traceback: errorMessage, + // We don't have these fields from the connection test error, but the component handles undefined + error_class: undefined, + llm_provider: undefined, + error_code: undefined + }; + + return ( + +
+ + + {/* Use the ErrorViewer component for consistent error display */} + + + + +
+ +
+
+ + ); +}; + +export default ConnectionErrorDisplay; \ No newline at end of file diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index 19589400a0e..1603d2ae26f 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -2274,6 +2274,52 @@ export const keyInfoCall = async (accessToken: String, keys: String[]) => { }; +export const testConnectionRequest = async ( + accessToken: string, + requestBody: Record +) => { + try { + console.log("Sending model connection test request:", JSON.stringify(requestBody)); + + // Construct the URL based on environment + const url = proxyBaseUrl ? `${proxyBaseUrl}/health/test_connection` : `/health/test_connection`; + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + [globalLitellmHeaderName]: `Bearer ${accessToken}` + }, + body: JSON.stringify(requestBody) + }); + + // Check for non-JSON responses first + const contentType = response.headers.get('content-type'); + if (!contentType || !contentType.includes('application/json')) { + const text = await response.text(); + console.error("Received non-JSON response:", text); + throw new Error(`Received non-JSON response (${response.status}: ${response.statusText}). Check network tab for details.`); + } + + const data = await response.json(); + + if (!response.ok || data.status === "error") { + // Handle the specific error format you're receiving + if (data.status === "error" && data.result && data.result.error) { + throw new Error(data.result.error); + } else { + throw new Error(data.error?.message || `Connection test failed: ${response.status} ${response.statusText}`); + } + } + + return data; + } catch (error) { + console.error("Model connection test error:", error); + throw error; + } +}; + +// ... existing code ... export const keyInfoV1Call = async (accessToken: string, key: string) => { try { let url = proxyBaseUrl ? `${proxyBaseUrl}/key/info` : `/key/info`;