Merge pull request #1826 from xKevIsDev/error-fix
fix: enhanced error handling for llm api, general cleanup
This commit is contained in:
@@ -4,8 +4,6 @@ export * from './useShortcuts';
|
||||
export * from './StickToBottom';
|
||||
export * from './useEditChatDescription';
|
||||
export { default } from './useViewport';
|
||||
export { useUpdateCheck } from './useUpdateCheck';
|
||||
export { useFeatures } from './useFeatures';
|
||||
export { useNotifications } from './useNotifications';
|
||||
export { useConnectionStatus } from './useConnectionStatus';
|
||||
export { useDebugStatus } from './useDebugStatus';
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { getDebugStatus, acknowledgeWarning, acknowledgeError, type DebugIssue } from '~/lib/api/debug';
|
||||
|
||||
const ACKNOWLEDGED_DEBUG_ISSUES_KEY = 'bolt_acknowledged_debug_issues';
|
||||
|
||||
const getAcknowledgedIssues = (): string[] => {
|
||||
try {
|
||||
const stored = localStorage.getItem(ACKNOWLEDGED_DEBUG_ISSUES_KEY);
|
||||
return stored ? JSON.parse(stored) : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const setAcknowledgedIssues = (issueIds: string[]) => {
|
||||
try {
|
||||
localStorage.setItem(ACKNOWLEDGED_DEBUG_ISSUES_KEY, JSON.stringify(issueIds));
|
||||
} catch (error) {
|
||||
console.error('Failed to persist acknowledged debug issues:', error);
|
||||
}
|
||||
};
|
||||
|
||||
export const useDebugStatus = () => {
|
||||
const [hasActiveWarnings, setHasActiveWarnings] = useState(false);
|
||||
const [activeIssues, setActiveIssues] = useState<DebugIssue[]>([]);
|
||||
const [acknowledgedIssueIds, setAcknowledgedIssueIds] = useState<string[]>(() => getAcknowledgedIssues());
|
||||
|
||||
const checkDebugStatus = async () => {
|
||||
try {
|
||||
const status = await getDebugStatus();
|
||||
const issues: DebugIssue[] = [
|
||||
...status.warnings.map((w) => ({ ...w, type: 'warning' as const })),
|
||||
...status.errors.map((e) => ({ ...e, type: 'error' as const })),
|
||||
].filter((issue) => !acknowledgedIssueIds.includes(issue.id));
|
||||
|
||||
setActiveIssues(issues);
|
||||
setHasActiveWarnings(issues.length > 0);
|
||||
} catch (error) {
|
||||
console.error('Failed to check debug status:', error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Check immediately and then every 5 seconds
|
||||
checkDebugStatus();
|
||||
|
||||
const interval = setInterval(checkDebugStatus, 5 * 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [acknowledgedIssueIds]);
|
||||
|
||||
const acknowledgeIssue = async (issue: DebugIssue) => {
|
||||
try {
|
||||
if (issue.type === 'warning') {
|
||||
await acknowledgeWarning(issue.id);
|
||||
} else {
|
||||
await acknowledgeError(issue.id);
|
||||
}
|
||||
|
||||
const newAcknowledgedIds = [...acknowledgedIssueIds, issue.id];
|
||||
setAcknowledgedIssueIds(newAcknowledgedIds);
|
||||
setAcknowledgedIssues(newAcknowledgedIds);
|
||||
setActiveIssues((prev) => prev.filter((i) => i.id !== issue.id));
|
||||
setHasActiveWarnings(activeIssues.length > 1);
|
||||
} catch (error) {
|
||||
console.error('Failed to acknowledge issue:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const acknowledgeAllIssues = async () => {
|
||||
try {
|
||||
await Promise.all(
|
||||
activeIssues.map((issue) =>
|
||||
issue.type === 'warning' ? acknowledgeWarning(issue.id) : acknowledgeError(issue.id),
|
||||
),
|
||||
);
|
||||
|
||||
const newAcknowledgedIds = [...acknowledgedIssueIds, ...activeIssues.map((i) => i.id)];
|
||||
setAcknowledgedIssueIds(newAcknowledgedIds);
|
||||
setAcknowledgedIssues(newAcknowledgedIds);
|
||||
setActiveIssues([]);
|
||||
setHasActiveWarnings(false);
|
||||
} catch (error) {
|
||||
console.error('Failed to acknowledge all issues:', error);
|
||||
}
|
||||
};
|
||||
|
||||
return { hasActiveWarnings, activeIssues, acknowledgeIssue, acknowledgeAllIssues };
|
||||
};
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
autoSelectStarterTemplate,
|
||||
enableContextOptimizationStore,
|
||||
tabConfigurationStore,
|
||||
updateTabConfiguration as updateTabConfig,
|
||||
resetTabConfiguration as resetTabConfig,
|
||||
updateProviderSettings as updateProviderSettingsStore,
|
||||
updateLatestBranch,
|
||||
@@ -20,7 +19,7 @@ import {
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import Cookies from 'js-cookie';
|
||||
import type { IProviderSetting, ProviderInfo, IProviderConfig } from '~/types/model';
|
||||
import type { TabWindowConfig, TabVisibilityConfig } from '~/components/@settings/core/types';
|
||||
import type { TabWindowConfig } from '~/components/@settings/core/types';
|
||||
import { logStore } from '~/lib/stores/logs';
|
||||
import { getLocalStorage, setLocalStorage } from '~/lib/persistence';
|
||||
|
||||
@@ -62,7 +61,6 @@ export interface UseSettingsReturn {
|
||||
|
||||
// Tab configuration
|
||||
tabConfiguration: TabWindowConfig;
|
||||
updateTabConfiguration: (config: TabVisibilityConfig) => void;
|
||||
resetTabConfiguration: () => void;
|
||||
}
|
||||
|
||||
@@ -205,7 +203,6 @@ export function useSettings(): UseSettingsReturn {
|
||||
setTimezone,
|
||||
settings,
|
||||
tabConfiguration,
|
||||
updateTabConfiguration: updateTabConfig,
|
||||
resetTabConfiguration: resetTabConfig,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { checkForUpdates, acknowledgeUpdate } from '~/lib/api/updates';
|
||||
|
||||
const LAST_ACKNOWLEDGED_VERSION_KEY = 'bolt_last_acknowledged_version';
|
||||
|
||||
export const useUpdateCheck = () => {
|
||||
const [hasUpdate, setHasUpdate] = useState(false);
|
||||
const [currentVersion, setCurrentVersion] = useState<string>('');
|
||||
const [lastAcknowledgedVersion, setLastAcknowledgedVersion] = useState<string | null>(() => {
|
||||
try {
|
||||
return localStorage.getItem(LAST_ACKNOWLEDGED_VERSION_KEY);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const checkUpdate = async () => {
|
||||
try {
|
||||
const { available, version } = await checkForUpdates();
|
||||
setCurrentVersion(version);
|
||||
|
||||
// Only show update if it's a new version and hasn't been acknowledged
|
||||
setHasUpdate(available && version !== lastAcknowledgedVersion);
|
||||
} catch (error) {
|
||||
console.error('Failed to check for updates:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// Check immediately and then every 30 minutes
|
||||
checkUpdate();
|
||||
|
||||
const interval = setInterval(checkUpdate, 30 * 60 * 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [lastAcknowledgedVersion]);
|
||||
|
||||
const handleAcknowledgeUpdate = async () => {
|
||||
try {
|
||||
const { version } = await checkForUpdates();
|
||||
await acknowledgeUpdate(version);
|
||||
|
||||
// Store in localStorage
|
||||
try {
|
||||
localStorage.setItem(LAST_ACKNOWLEDGED_VERSION_KEY, version);
|
||||
} catch (error) {
|
||||
console.error('Failed to persist acknowledged version:', error);
|
||||
}
|
||||
|
||||
setLastAcknowledgedVersion(version);
|
||||
setHasUpdate(false);
|
||||
} catch (error) {
|
||||
console.error('Failed to acknowledge update:', error);
|
||||
}
|
||||
};
|
||||
|
||||
return { hasUpdate, currentVersion, acknowledgeUpdate: handleAcknowledgeUpdate };
|
||||
};
|
||||
@@ -1,14 +1,8 @@
|
||||
import { atom, map } from 'nanostores';
|
||||
import { PROVIDER_LIST } from '~/utils/constants';
|
||||
import type { IProviderConfig } from '~/types/model';
|
||||
import type {
|
||||
TabVisibilityConfig,
|
||||
TabWindowConfig,
|
||||
UserTabConfig,
|
||||
DevTabConfig,
|
||||
} from '~/components/@settings/core/types';
|
||||
import type { TabVisibilityConfig, TabWindowConfig, UserTabConfig } from '~/components/@settings/core/types';
|
||||
import { DEFAULT_TAB_CONFIG } from '~/components/@settings/core/constants';
|
||||
import Cookies from 'js-cookie';
|
||||
import { toggleTheme } from './theme';
|
||||
import { create } from 'zustand';
|
||||
|
||||
@@ -202,7 +196,6 @@ export const updatePromptId = (id: string) => {
|
||||
const getInitialTabConfiguration = (): TabWindowConfig => {
|
||||
const defaultConfig: TabWindowConfig = {
|
||||
userTabs: DEFAULT_TAB_CONFIG.filter((tab): tab is UserTabConfig => tab.window === 'user'),
|
||||
developerTabs: DEFAULT_TAB_CONFIG.filter((tab): tab is DevTabConfig => tab.window === 'developer'),
|
||||
};
|
||||
|
||||
if (!isBrowser) {
|
||||
@@ -218,16 +211,13 @@ const getInitialTabConfiguration = (): TabWindowConfig => {
|
||||
|
||||
const parsed = JSON.parse(saved);
|
||||
|
||||
if (!parsed?.userTabs || !parsed?.developerTabs) {
|
||||
if (!parsed?.userTabs) {
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
// Ensure proper typing of loaded configuration
|
||||
return {
|
||||
userTabs: parsed.userTabs.filter((tab: TabVisibilityConfig): tab is UserTabConfig => tab.window === 'user'),
|
||||
developerTabs: parsed.developerTabs.filter(
|
||||
(tab: TabVisibilityConfig): tab is DevTabConfig => tab.window === 'developer',
|
||||
),
|
||||
};
|
||||
} catch (error) {
|
||||
console.warn('Failed to parse tab configuration:', error);
|
||||
@@ -239,60 +229,16 @@ const getInitialTabConfiguration = (): TabWindowConfig => {
|
||||
|
||||
export const tabConfigurationStore = map<TabWindowConfig>(getInitialTabConfiguration());
|
||||
|
||||
// Helper function to update tab configuration
|
||||
export const updateTabConfiguration = (config: TabVisibilityConfig) => {
|
||||
const currentConfig = tabConfigurationStore.get();
|
||||
console.log('Current tab configuration before update:', currentConfig);
|
||||
|
||||
const isUserTab = config.window === 'user';
|
||||
const targetArray = isUserTab ? 'userTabs' : 'developerTabs';
|
||||
|
||||
// Only update the tab in its respective window
|
||||
const updatedTabs = currentConfig[targetArray].map((tab) => (tab.id === config.id ? { ...config } : tab));
|
||||
|
||||
// If tab doesn't exist in this window yet, add it
|
||||
if (!updatedTabs.find((tab) => tab.id === config.id)) {
|
||||
updatedTabs.push(config);
|
||||
}
|
||||
|
||||
// Create new config, only updating the target window's tabs
|
||||
const newConfig: TabWindowConfig = {
|
||||
...currentConfig,
|
||||
[targetArray]: updatedTabs,
|
||||
};
|
||||
|
||||
console.log('New tab configuration after update:', newConfig);
|
||||
|
||||
tabConfigurationStore.set(newConfig);
|
||||
Cookies.set('tabConfiguration', JSON.stringify(newConfig), {
|
||||
expires: 365, // Set cookie to expire in 1 year
|
||||
path: '/',
|
||||
sameSite: 'strict',
|
||||
});
|
||||
};
|
||||
|
||||
// Helper function to reset tab configuration
|
||||
export const resetTabConfiguration = () => {
|
||||
const defaultConfig: TabWindowConfig = {
|
||||
userTabs: DEFAULT_TAB_CONFIG.filter((tab): tab is UserTabConfig => tab.window === 'user'),
|
||||
developerTabs: DEFAULT_TAB_CONFIG.filter((tab): tab is DevTabConfig => tab.window === 'developer'),
|
||||
};
|
||||
|
||||
tabConfigurationStore.set(defaultConfig);
|
||||
localStorage.setItem('bolt_tab_configuration', JSON.stringify(defaultConfig));
|
||||
};
|
||||
|
||||
// Developer mode store with persistence
|
||||
export const developerModeStore = atom<boolean>(initialSettings.developerMode);
|
||||
|
||||
export const setDeveloperMode = (value: boolean) => {
|
||||
developerModeStore.set(value);
|
||||
|
||||
if (isBrowser) {
|
||||
localStorage.setItem(SETTINGS_KEYS.DEVELOPER_MODE, JSON.stringify(value));
|
||||
}
|
||||
};
|
||||
|
||||
// First, let's define the SettingsStore interface
|
||||
interface SettingsStore {
|
||||
isOpen: boolean;
|
||||
|
||||
@@ -10,22 +10,19 @@ export interface TabConfig {
|
||||
|
||||
interface TabConfigurationStore {
|
||||
userTabs: TabConfig[];
|
||||
developerTabs: TabConfig[];
|
||||
get: () => { userTabs: TabConfig[]; developerTabs: TabConfig[] };
|
||||
set: (config: { userTabs: TabConfig[]; developerTabs: TabConfig[] }) => void;
|
||||
get: () => { userTabs: TabConfig[] };
|
||||
set: (config: { userTabs: TabConfig[] }) => void;
|
||||
reset: () => void;
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG = {
|
||||
userTabs: [],
|
||||
developerTabs: [],
|
||||
};
|
||||
|
||||
export const tabConfigurationStore = create<TabConfigurationStore>((set, get) => ({
|
||||
...DEFAULT_CONFIG,
|
||||
get: () => ({
|
||||
userTabs: get().userTabs,
|
||||
developerTabs: get().developerTabs,
|
||||
}),
|
||||
set: (config) => set(config),
|
||||
reset: () => set(DEFAULT_CONFIG),
|
||||
|
||||
Reference in New Issue
Block a user