diff --git a/frontend/src/routes/_oh.tsx b/frontend/src/routes/_oh.tsx
index 2d2597f2a4..7d31465b3e 100644
--- a/frontend/src/routes/_oh.tsx
+++ b/frontend/src/routes/_oh.tsx
@@ -91,6 +91,12 @@ export function ErrorBoundary() {
);
}
+type SettingsFormData = {
+ models: string[];
+ agents: string[];
+ securityAnalyzers: string[];
+};
+
export default function MainApp() {
const { stop, isConnected } = useSocket();
const navigation = useNavigation();
@@ -105,28 +111,31 @@ export default function MainApp() {
const [settingsModalIsOpen, setSettingsModalIsOpen] = React.useState(false);
const [startNewProjectModalIsOpen, setStartNewProjectModalIsOpen] =
React.useState(false);
- const [data, setData] = React.useState<{
- models: string[];
- agents: string[];
- securityAnalyzers: string[];
- }>({
- models: [],
- agents: [],
- securityAnalyzers: [],
- });
+ const [settingsFormData, setSettingsFormData] =
+ React.useState
({
+ models: [],
+ agents: [],
+ securityAnalyzers: [],
+ });
+ const [settingsFormError, setSettingsFormError] = React.useState<
+ string | null
+ >(null);
React.useEffect(() => {
// We fetch this here instead of the data loader because the server seems to block
// the retrieval when the session is closing -- preventing the screen from rendering until
// the fetch is complete
(async () => {
- const [models, agents, securityAnalyzers] = await Promise.all([
- OpenHands.getModels(),
- OpenHands.getAgents(),
- OpenHands.getSecurityAnalyzers(),
- ]);
-
- setData({ models, agents, securityAnalyzers });
+ try {
+ const [models, agents, securityAnalyzers] = await Promise.all([
+ OpenHands.getModels(),
+ OpenHands.getAgents(),
+ OpenHands.getSecurityAnalyzers(),
+ ]);
+ setSettingsFormData({ models, agents, securityAnalyzers });
+ } catch (error) {
+ setSettingsFormError("Failed to load settings, please reload the page");
+ }
})();
}, []);
@@ -233,6 +242,9 @@ export default function MainApp() {
{(!settingsIsUpdated || settingsModalIsOpen) && (
setSettingsModalIsOpen(false)}>
+ {settingsFormError && (
+
{settingsFormError}
+ )}
AI Provider Configuration
@@ -247,9 +259,9 @@ export default function MainApp() {
)}
setSettingsModalIsOpen(false)}
/>
diff --git a/frontend/src/utils/download-workspace.ts b/frontend/src/utils/download-workspace.ts
index 90ae924544..1bbf30612d 100644
--- a/frontend/src/utils/download-workspace.ts
+++ b/frontend/src/utils/download-workspace.ts
@@ -4,22 +4,18 @@ import OpenHands from "#/api/open-hands";
* Downloads the current workspace as a .zip file.
*/
export const downloadWorkspace = async () => {
- try {
- const token = localStorage.getItem("token");
- if (!token) {
- throw new Error("No token found");
- }
-
- const blob = await OpenHands.getWorkspaceZip(token);
-
- const url = URL.createObjectURL(blob);
- const link = document.createElement("a");
- link.href = url;
- link.setAttribute("download", "workspace.zip");
- document.body.appendChild(link);
- link.click();
- link.parentNode?.removeChild(link);
- } catch (e) {
- console.error("Failed to download workspace as .zip", e);
+ const token = localStorage.getItem("token");
+ if (!token) {
+ throw new Error("No token found");
}
+
+ const blob = await OpenHands.getWorkspaceZip(token);
+
+ const url = URL.createObjectURL(blob);
+ const link = document.createElement("a");
+ link.href = url;
+ link.setAttribute("download", "workspace.zip");
+ document.body.appendChild(link);
+ link.click();
+ link.parentNode?.removeChild(link);
};