Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions sky/dashboard/src/components/elements/version-display.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ export function VersionDisplay() {

const getVersion = async () => {
const data = await apiClient.get('/api/health');
if (!data.ok) {
console.error(
`API request /api/health failed with status ${data.status}`
);
return;
}
const healthData = await data.json();
if (healthData.version) {
setVersion(healthData.version);
Expand Down
31 changes: 21 additions & 10 deletions sky/dashboard/src/components/workspaces.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,9 @@ export async function getWorkspaceClusters(workspaceName) {
);
return filteredClusters;
} catch (error) {
console.error(
`Error fetching clusters for workspace ${workspaceName}:`,
error
);
return [];
const msg = `Error fetching clusters for workspace ${workspaceName}: ${error.message}`;
console.error(msg);
throw new Error(msg);
}
}

Expand All @@ -112,8 +110,23 @@ export async function getWorkspaceManagedJobs(workspaceName) {
override_skypilot_config: { active_workspace: workspaceName },
});

// Check if initial request succeeded
if (!response.ok) {
const msg = `Initial API request to get managed jobs failed with status ${response.status} for workspace ${workspaceName}`;
throw new Error(msg);
}

const id = response.headers.get('X-Skypilot-Request-ID');
// Handle empty request ID
if (!id) {
const msg = `No request ID received from server for getting managed jobs for workspace ${workspaceName}`;
throw new Error(msg);
}
const fetchedData = await apiClient.get(`/api/get?request_id=${id}`);
if (!fetchedData.ok) {
const msg = `API request to get managed jobs result failed with status ${fetchedData.status} for workspace ${workspaceName}`;
throw new Error(msg);
}
const data = await fetchedData.json();
const jobsData = data.return_value
? JSON.parse(data.return_value)
Expand All @@ -134,11 +147,9 @@ export async function getWorkspaceManagedJobs(workspaceName) {

return jobsData;
} catch (error) {
console.error(
`Error fetching managed jobs for workspace ${workspaceName}:`,
error
);
return { jobs: [] };
const msg = `Error fetching managed jobs for workspace ${workspaceName}: ${error.message}`;
console.error(msg);
throw new Error(msg);
}
}

Expand Down
74 changes: 52 additions & 22 deletions sky/dashboard/src/data/connectors/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,57 @@ import { ENDPOINT } from './constants';

export const apiClient = {
fetch: async (path, body, method = 'POST') => {
const headers =
method === 'POST'
? {
'Content-Type': 'application/json',
}
: {};
try {
const headers =
method === 'POST'
? {
'Content-Type': 'application/json',
}
: {};

const baseUrl = window.location.origin;
const fullUrl = `${baseUrl}${ENDPOINT}${path}`;
const baseUrl = window.location.origin;
const fullUrl = `${baseUrl}${ENDPOINT}${path}`;

const response = await fetch(fullUrl, {
method,
headers,
body: method === 'POST' ? JSON.stringify(body) : undefined,
});
const response = await fetch(fullUrl, {
method,
headers,
body: method === 'POST' ? JSON.stringify(body) : undefined,
});

// Check if initial request succeeded
if (!response.ok) {
const msg = `Initial API request ${path} failed with status ${response.status}`;
throw new Error(msg);
}

// Handle X-Request-ID for API requests
const id =
response.headers.get('X-Skypilot-Request-ID') ||
response.headers.get('X-Request-ID');
// Handle X-Request-ID for API requests
const id =
response.headers.get('X-Skypilot-Request-ID') ||
response.headers.get('X-Request-ID');

const fetchedData = await fetch(
`${baseUrl}${ENDPOINT}/api/get?request_id=${id}`
);
const data = await fetchedData.json();
return data.return_value ? JSON.parse(data.return_value) : [];
// Handle empty request ID
if (!id) {
const msg = `No request ID received from server for ${path}`;
throw new Error(msg);
}

const fetchedData = await fetch(
`${baseUrl}${ENDPOINT}/api/get?request_id=${id}`
);

// Handle all error status codes (4xx, 5xx, etc.)
if (!fetchedData.ok) {
const msg = `API request to get ${path} result failed with status ${fetchedData.status}`;
throw new Error(msg);
}

const data = await fetchedData.json();
return data.return_value ? JSON.parse(data.return_value) : [];
} catch (error) {
const msg = `Error in apiClient.fetch for ${path}: ${error.message}`;
console.error(msg);
throw new Error(msg);
}
},

// Helper method for POST requests
Expand All @@ -51,6 +76,11 @@ export const apiClient = {
// Helper method for streaming responses
stream: async (path, body, onData) => {
const response = await apiClient.post(path, body);
if (!response.ok) {
const msg = `API request ${path} failed with status ${response.status}`;
console.error(msg);
throw new Error(msg);
}
const reader = response.body.getReader();

try {
Expand Down
6 changes: 3 additions & 3 deletions sky/dashboard/src/data/connectors/clusters.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export async function getClusters({ clusterNames = null } = {}) {
return clusterData;
} catch (error) {
console.error('Error fetching clusters:', error);
return [];
throw error;
}
}

Expand Down Expand Up @@ -186,7 +186,7 @@ export async function getClusterHistory(clusterHash = null, days = 30) {
return historyData;
} catch (error) {
console.error('Error fetching cluster history:', error);
return [];
throw error;
}
}

Expand Down Expand Up @@ -317,7 +317,7 @@ export async function getClusterJobs({ clusterName, workspace }) {
return jobData;
} catch (error) {
console.error('Error fetching cluster jobs:', error);
return [];
throw error;
}
}

Expand Down
Loading
Loading