mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 09:33:10 -07:00
better logger util
This commit is contained in:
parent
4420a62395
commit
1298debaa8
17 changed files with 130 additions and 167 deletions
10
src/App.tsx
10
src/App.tsx
|
|
@ -11,7 +11,7 @@ import { ScreenTransition } from '@/components/ScreenTransition';
|
||||||
import { TitleBar } from '@/components/TitleBar';
|
import { TitleBar } from '@/components/TitleBar';
|
||||||
import { useUpdateChecker } from '@/hooks/useUpdateChecker';
|
import { useUpdateChecker } from '@/hooks/useUpdateChecker';
|
||||||
import { useKoboldVersions } from '@/hooks/useKoboldVersions';
|
import { useKoboldVersions } from '@/hooks/useKoboldVersions';
|
||||||
import { Logger } from '@/utils/logger';
|
import { safeExecute } from '@/utils/logger';
|
||||||
import { TITLEBAR_HEIGHT } from '@/constants';
|
import { TITLEBAR_HEIGHT } from '@/constants';
|
||||||
import type { DownloadItem } from '@/types/electron';
|
import type { DownloadItem } from '@/types/electron';
|
||||||
import type { InterfaceTab, FrontendPreference, Screen } from '@/types';
|
import type { InterfaceTab, FrontendPreference, Screen } from '@/types';
|
||||||
|
|
@ -46,7 +46,7 @@ export const App = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkInstallation = async () => {
|
const checkInstallation = async () => {
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
const [currentVersion, hasSeenWelcome, preference] = await Promise.all([
|
const [currentVersion, hasSeenWelcome, preference] = await Promise.all([
|
||||||
window.electronAPI.kobold.getCurrentVersion(),
|
window.electronAPI.kobold.getCurrentVersion(),
|
||||||
window.electronAPI.config.get('hasSeenWelcome') as Promise<boolean>,
|
window.electronAPI.config.get('hasSeenWelcome') as Promise<boolean>,
|
||||||
|
|
@ -80,7 +80,7 @@ export const App = () => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleBinaryUpdate = async (download: DownloadItem) => {
|
const handleBinaryUpdate = async (download: DownloadItem) => {
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
const success = await sharedHandleDownload({
|
const success = await sharedHandleDownload({
|
||||||
item: download,
|
item: download,
|
||||||
isUpdate: true,
|
isUpdate: true,
|
||||||
|
|
@ -94,7 +94,7 @@ export const App = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDownloadComplete = async () => {
|
const handleDownloadComplete = async () => {
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
await window.electronAPI.kobold.getCurrentVersion();
|
await window.electronAPI.kobold.getCurrentVersion();
|
||||||
}, 'Error refreshing versions after download:');
|
}, 'Error refreshing versions after download:');
|
||||||
|
|
||||||
|
|
@ -241,7 +241,7 @@ export const App = () => {
|
||||||
opened={settingsOpened}
|
opened={settingsOpened}
|
||||||
onClose={async () => {
|
onClose={async () => {
|
||||||
setSettingsOpened(false);
|
setSettingsOpened(false);
|
||||||
const preference = await Logger.safeExecute(
|
const preference = await safeExecute(
|
||||||
() =>
|
() =>
|
||||||
window.electronAPI.config.get(
|
window.electronAPI.config.get(
|
||||||
'frontendPreference'
|
'frontendPreference'
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import { useState } from 'react';
|
||||||
import type { InstalledVersion, DownloadItem } from '@/types/electron';
|
import type { InstalledVersion, DownloadItem } from '@/types/electron';
|
||||||
import { getDisplayNameFromPath } from '@/utils/version';
|
import { getDisplayNameFromPath } from '@/utils/version';
|
||||||
import { GITHUB_API } from '@/constants';
|
import { GITHUB_API } from '@/constants';
|
||||||
import { Logger } from '@/utils/logger';
|
import { safeExecute } from '@/utils/logger';
|
||||||
|
|
||||||
interface UpdateAvailableModalProps {
|
interface UpdateAvailableModalProps {
|
||||||
opened: boolean;
|
opened: boolean;
|
||||||
|
|
@ -39,7 +39,7 @@ export const UpdateAvailableModal = ({
|
||||||
|
|
||||||
const handleUpdate = async () => {
|
const handleUpdate = async () => {
|
||||||
setIsUpdating(true);
|
setIsUpdating(true);
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
await onUpdate(availableUpdate);
|
await onUpdate(availableUpdate);
|
||||||
onClose();
|
onClose();
|
||||||
}, 'Failed to update:');
|
}, 'Failed to update:');
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { getPlatformDisplayName } from '@/utils/platform';
|
||||||
import { formatDownloadSize } from '@/utils/download';
|
import { formatDownloadSize } from '@/utils/download';
|
||||||
import { getAssetDescription, sortDownloadsByType } from '@/utils/assets';
|
import { getAssetDescription, sortDownloadsByType } from '@/utils/assets';
|
||||||
import { useKoboldVersions } from '@/hooks/useKoboldVersions';
|
import { useKoboldVersions } from '@/hooks/useKoboldVersions';
|
||||||
import { Logger } from '@/utils/logger';
|
import { safeExecute } from '@/utils/logger';
|
||||||
import type { DownloadItem } from '@/types/electron';
|
import type { DownloadItem } from '@/types/electron';
|
||||||
|
|
||||||
interface DownloadScreenProps {
|
interface DownloadScreenProps {
|
||||||
|
|
@ -34,7 +34,7 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
|
||||||
async (download: DownloadItem) => {
|
async (download: DownloadItem) => {
|
||||||
setDownloadingAsset(download.name);
|
setDownloadingAsset(download.name);
|
||||||
|
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
const success = await sharedHandleDownload({
|
const success = await sharedHandleDownload({
|
||||||
item: download,
|
item: download,
|
||||||
isUpdate: false,
|
isUpdate: false,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { useState, useEffect } from 'react';
|
||||||
import { InfoTooltip } from '@/components/InfoTooltip';
|
import { InfoTooltip } from '@/components/InfoTooltip';
|
||||||
import { CheckboxWithTooltip } from '@/components/CheckboxWithTooltip';
|
import { CheckboxWithTooltip } from '@/components/CheckboxWithTooltip';
|
||||||
import { useLaunchConfig } from '@/hooks/useLaunchConfig';
|
import { useLaunchConfig } from '@/hooks/useLaunchConfig';
|
||||||
import { Logger } from '@/utils/logger';
|
import { safeExecute } from '@/utils/logger';
|
||||||
|
|
||||||
export const AdvancedTab = () => {
|
export const AdvancedTab = () => {
|
||||||
const {
|
const {
|
||||||
|
|
@ -39,7 +39,7 @@ export const AdvancedTab = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const detectBackendSupport = async () => {
|
const detectBackendSupport = async () => {
|
||||||
const support = await Logger.safeExecute(
|
const support = await safeExecute(
|
||||||
() => window.electronAPI.kobold.detectBackendSupport(),
|
() => window.electronAPI.kobold.detectBackendSupport(),
|
||||||
'Failed to detect backend support:'
|
'Failed to detect backend support:'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { InfoTooltip } from '@/components/InfoTooltip';
|
||||||
import { BackendSelectItem } from '@/components/screens/Launch/GeneralTab/BackendSelectItem';
|
import { BackendSelectItem } from '@/components/screens/Launch/GeneralTab/BackendSelectItem';
|
||||||
import { GpuDeviceSelector } from '@/components/screens/Launch/GeneralTab/GpuDeviceSelector';
|
import { GpuDeviceSelector } from '@/components/screens/Launch/GeneralTab/GpuDeviceSelector';
|
||||||
import { useLaunchConfig } from '@/hooks/useLaunchConfig';
|
import { useLaunchConfig } from '@/hooks/useLaunchConfig';
|
||||||
import { Logger } from '@/utils/logger';
|
import { safeExecute } from '@/utils/logger';
|
||||||
import type { BackendOption } from '@/types';
|
import type { BackendOption } from '@/types';
|
||||||
|
|
||||||
export const BackendSelector = () => {
|
export const BackendSelector = () => {
|
||||||
|
|
@ -26,7 +26,7 @@ export const BackendSelector = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadBackends = async () => {
|
const loadBackends = async () => {
|
||||||
setIsLoadingBackends(true);
|
setIsLoadingBackends(true);
|
||||||
const backends = await Logger.safeExecute(
|
const backends = await safeExecute(
|
||||||
() => window.electronAPI.kobold.getAvailableBackends(true),
|
() => window.electronAPI.kobold.getAvailableBackends(true),
|
||||||
'Failed to detect available backends:'
|
'Failed to detect available backends:'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Card, Container, Stack, Tabs, Group, Button } from '@mantine/core';
|
import { Card, Container, Stack, Tabs, Group, Button } from '@mantine/core';
|
||||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||||
|
import { tryExecute, error, safeExecute } from '@/utils/logger';
|
||||||
import { useLaunchConfig } from '@/hooks/useLaunchConfig';
|
import { useLaunchConfig } from '@/hooks/useLaunchConfig';
|
||||||
import { useLaunchLogic } from '@/hooks/useLaunchLogic';
|
import { useLaunchLogic } from '@/hooks/useLaunchLogic';
|
||||||
import { useWarnings } from '@/hooks/useWarnings';
|
import { useWarnings } from '@/hooks/useWarnings';
|
||||||
|
|
@ -10,7 +11,6 @@ import { ImageGenerationTab } from '@/components/screens/Launch/ImageGenerationT
|
||||||
import { WarningDisplay } from '@/components/WarningDisplay';
|
import { WarningDisplay } from '@/components/WarningDisplay';
|
||||||
import { ConfigFileManager } from '@/components/screens/Launch/ConfigFileManager';
|
import { ConfigFileManager } from '@/components/screens/Launch/ConfigFileManager';
|
||||||
import { DEFAULT_MODEL_URL } from '@/constants';
|
import { DEFAULT_MODEL_URL } from '@/constants';
|
||||||
import { Logger } from '@/utils/logger';
|
|
||||||
import type { ConfigFile } from '@/types';
|
import type { ConfigFile } from '@/types';
|
||||||
|
|
||||||
interface LaunchScreenProps {
|
interface LaunchScreenProps {
|
||||||
|
|
@ -86,7 +86,7 @@ export const LaunchScreen = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const setHappyDefaults = useCallback(async () => {
|
const setHappyDefaults = useCallback(async () => {
|
||||||
const backends = await Logger.safeExecute(
|
const backends = await safeExecute(
|
||||||
() => window.electronAPI.kobold.getAvailableBackends(),
|
() => window.electronAPI.kobold.getAvailableBackends(),
|
||||||
'Failed to set defaults:'
|
'Failed to set defaults:'
|
||||||
);
|
);
|
||||||
|
|
@ -98,7 +98,7 @@ export const LaunchScreen = ({
|
||||||
|
|
||||||
const setInitialDefaults = useCallback(
|
const setInitialDefaults = useCallback(
|
||||||
async (currentModelPath: string, currentSdModel: string) => {
|
async (currentModelPath: string, currentSdModel: string) => {
|
||||||
await Logger.tryExecute(async () => {
|
await tryExecute(async () => {
|
||||||
if (
|
if (
|
||||||
!defaultsSetRef.current &&
|
!defaultsSetRef.current &&
|
||||||
!currentModelPath.trim() &&
|
!currentModelPath.trim() &&
|
||||||
|
|
@ -190,7 +190,7 @@ export const LaunchScreen = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCreateNewConfig = async (configName: string) => {
|
const handleCreateNewConfig = async (configName: string) => {
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
const fullConfigName = `${configName}.json`;
|
const fullConfigName = `${configName}.json`;
|
||||||
const saveSuccess = await window.electronAPI.kobold.saveConfigFile(
|
const saveSuccess = await window.electronAPI.kobold.saveConfigFile(
|
||||||
fullConfigName,
|
fullConfigName,
|
||||||
|
|
@ -202,7 +202,7 @@ export const LaunchScreen = ({
|
||||||
setSelectedFile(fullConfigName);
|
setSelectedFile(fullConfigName);
|
||||||
await window.electronAPI.kobold.setSelectedConfig(fullConfigName);
|
await window.electronAPI.kobold.setSelectedConfig(fullConfigName);
|
||||||
} else {
|
} else {
|
||||||
Logger.error(
|
error(
|
||||||
'Failed to create new configuration',
|
'Failed to create new configuration',
|
||||||
new Error('Save operation failed')
|
new Error('Save operation failed')
|
||||||
);
|
);
|
||||||
|
|
@ -212,21 +212,21 @@ export const LaunchScreen = ({
|
||||||
|
|
||||||
const handleSaveConfig = async () => {
|
const handleSaveConfig = async () => {
|
||||||
if (!selectedFile) {
|
if (!selectedFile) {
|
||||||
Logger.error(
|
error(
|
||||||
'No configuration file selected for saving',
|
'No configuration file selected for saving',
|
||||||
new Error('Selected file is null')
|
new Error('Selected file is null')
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const success = await Logger.safeExecute(async () => {
|
const success = await safeExecute(async () => {
|
||||||
const saveSuccess = await window.electronAPI.kobold.saveConfigFile(
|
const saveSuccess = await window.electronAPI.kobold.saveConfigFile(
|
||||||
selectedFile,
|
selectedFile,
|
||||||
buildConfigData()
|
buildConfigData()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!saveSuccess) {
|
if (!saveSuccess) {
|
||||||
Logger.error(
|
error(
|
||||||
'Failed to save configuration',
|
'Failed to save configuration',
|
||||||
new Error('Save operation failed')
|
new Error('Save operation failed')
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import {
|
||||||
rem,
|
rem,
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { Github, FolderOpen } from 'lucide-react';
|
import { Github, FolderOpen } from 'lucide-react';
|
||||||
|
import { safeExecute } from '@/utils/logger';
|
||||||
import type { VersionInfo } from '@/types/electron';
|
import type { VersionInfo } from '@/types/electron';
|
||||||
import { PRODUCT_NAME } from '@/constants';
|
import { PRODUCT_NAME } from '@/constants';
|
||||||
import iconUrl from '/icon.png';
|
import iconUrl from '/icon.png';
|
||||||
|
|
@ -19,14 +20,12 @@ export const AboutTab = () => {
|
||||||
const [versionInfo, setVersionInfo] = useState<VersionInfo | null>(null);
|
const [versionInfo, setVersionInfo] = useState<VersionInfo | null>(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadVersionInfo = async () => {
|
const loadVersionInfo = async () => {
|
||||||
try {
|
const info = await safeExecute(
|
||||||
const info = await window.electronAPI.app.getVersionInfo();
|
() => window.electronAPI.app.getVersionInfo(),
|
||||||
|
'Failed to load version info'
|
||||||
|
);
|
||||||
|
if (info) {
|
||||||
setVersionInfo(info);
|
setVersionInfo(info);
|
||||||
} catch (error) {
|
|
||||||
window.electronAPI.logs.logError(
|
|
||||||
'Failed to load version info',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
loadVersionInfo();
|
loadVersionInfo();
|
||||||
|
|
@ -106,14 +105,10 @@ export const AboutTab = () => {
|
||||||
<FolderOpen style={{ width: rem(16), height: rem(16) }} />
|
<FolderOpen style={{ width: rem(16), height: rem(16) }} />
|
||||||
}
|
}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
await safeExecute(
|
||||||
await window.electronAPI.app.showLogsFolder();
|
() => window.electronAPI.app.showLogsFolder(),
|
||||||
} catch (error) {
|
'Failed to open logs folder'
|
||||||
window.electronAPI.logs.logError(
|
);
|
||||||
'Failed to open logs folder',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Show Logs
|
Show Logs
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
import { tryExecute, safeExecute } from '@/utils/logger';
|
||||||
import {
|
import {
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
|
|
@ -13,7 +14,6 @@ import { Folder, FolderOpen, Monitor } from 'lucide-react';
|
||||||
import styles from '@/styles/layout.module.css';
|
import styles from '@/styles/layout.module.css';
|
||||||
import type { FrontendPreference } from '@/types';
|
import type { FrontendPreference } from '@/types';
|
||||||
import { FRONTENDS } from '@/constants';
|
import { FRONTENDS } from '@/constants';
|
||||||
import { Logger } from '@/utils/logger';
|
|
||||||
|
|
||||||
export const GeneralTab = () => {
|
export const GeneralTab = () => {
|
||||||
const [installDir, setInstallDir] = useState<string>('');
|
const [installDir, setInstallDir] = useState<string>('');
|
||||||
|
|
@ -30,7 +30,7 @@ export const GeneralTab = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkNpxAvailability = async () => {
|
const checkNpxAvailability = async () => {
|
||||||
const available = await Logger.safeExecute(
|
const available = await safeExecute(
|
||||||
() => window.electronAPI.sillytavern.isNpxAvailable(),
|
() => window.electronAPI.sillytavern.isNpxAvailable(),
|
||||||
'Failed to check npx availability:'
|
'Failed to check npx availability:'
|
||||||
);
|
);
|
||||||
|
|
@ -39,7 +39,7 @@ export const GeneralTab = () => {
|
||||||
setIsNpxAvailable(isAvailable);
|
setIsNpxAvailable(isAvailable);
|
||||||
|
|
||||||
if (!isAvailable && FrontendPreference === 'sillytavern') {
|
if (!isAvailable && FrontendPreference === 'sillytavern') {
|
||||||
await Logger.tryExecute(
|
await tryExecute(
|
||||||
() =>
|
() =>
|
||||||
window.electronAPI.config.set('frontendPreference', 'koboldcpp'),
|
window.electronAPI.config.set('frontendPreference', 'koboldcpp'),
|
||||||
'Failed to reset frontend preference:'
|
'Failed to reset frontend preference:'
|
||||||
|
|
@ -54,7 +54,7 @@ export const GeneralTab = () => {
|
||||||
}, [FrontendPreference]);
|
}, [FrontendPreference]);
|
||||||
|
|
||||||
const loadCurrentInstallDir = async () => {
|
const loadCurrentInstallDir = async () => {
|
||||||
const currentDir = await Logger.safeExecute(
|
const currentDir = await safeExecute(
|
||||||
() => window.electronAPI.kobold.getCurrentInstallDir(),
|
() => window.electronAPI.kobold.getCurrentInstallDir(),
|
||||||
'Failed to load install directory:'
|
'Failed to load install directory:'
|
||||||
);
|
);
|
||||||
|
|
@ -64,7 +64,7 @@ export const GeneralTab = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadFrontendPreference = async () => {
|
const loadFrontendPreference = async () => {
|
||||||
const frontendPreference = await Logger.safeExecute(
|
const frontendPreference = await safeExecute(
|
||||||
() => window.electronAPI.config.get('frontendPreference'),
|
() => window.electronAPI.config.get('frontendPreference'),
|
||||||
'Failed to load frontend preference:'
|
'Failed to load frontend preference:'
|
||||||
);
|
);
|
||||||
|
|
@ -76,7 +76,7 @@ export const GeneralTab = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectInstallDir = async () => {
|
const handleSelectInstallDir = async () => {
|
||||||
const selectedDir = await Logger.safeExecute(
|
const selectedDir = await safeExecute(
|
||||||
() => window.electronAPI.kobold.selectInstallDirectory(),
|
() => window.electronAPI.kobold.selectInstallDirectory(),
|
||||||
'Failed to select install directory:'
|
'Failed to select install directory:'
|
||||||
);
|
);
|
||||||
|
|
@ -88,7 +88,7 @@ export const GeneralTab = () => {
|
||||||
const handleFrontendPreferenceChange = async (value: string | null) => {
|
const handleFrontendPreferenceChange = async (value: string | null) => {
|
||||||
if (!value || (value !== 'koboldcpp' && value !== 'sillytavern')) return;
|
if (!value || (value !== 'koboldcpp' && value !== 'sillytavern')) return;
|
||||||
|
|
||||||
const success = await Logger.tryExecute(
|
const success = await tryExecute(
|
||||||
() => window.electronAPI.config.set('frontendPreference', value),
|
() => window.electronAPI.config.set('frontendPreference', value),
|
||||||
'Failed to save frontend preference:'
|
'Failed to save frontend preference:'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import {
|
||||||
stripAssetExtensions,
|
stripAssetExtensions,
|
||||||
compareVersions,
|
compareVersions,
|
||||||
} from '@/utils/version';
|
} from '@/utils/version';
|
||||||
import { Logger } from '@/utils/logger';
|
import { safeExecute } from '@/utils/logger';
|
||||||
import { formatDownloadSize } from '@/utils/download';
|
import { formatDownloadSize } from '@/utils/download';
|
||||||
|
|
||||||
import { useKoboldVersions } from '@/hooks/useKoboldVersions';
|
import { useKoboldVersions } from '@/hooks/useKoboldVersions';
|
||||||
|
|
@ -63,7 +63,7 @@ export const VersionsTab = () => {
|
||||||
const loadInstalledVersions = useCallback(async () => {
|
const loadInstalledVersions = useCallback(async () => {
|
||||||
setLoadingInstalled(true);
|
setLoadingInstalled(true);
|
||||||
|
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
const [versions, currentVersion] = await Promise.all([
|
const [versions, currentVersion] = await Promise.all([
|
||||||
window.electronAPI.kobold.getInstalledVersions(),
|
window.electronAPI.kobold.getInstalledVersions(),
|
||||||
window.electronAPI.kobold.getCurrentVersion(),
|
window.electronAPI.kobold.getCurrentVersion(),
|
||||||
|
|
@ -77,7 +77,7 @@ export const VersionsTab = () => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const loadLatestRelease = useCallback(async () => {
|
const loadLatestRelease = useCallback(async () => {
|
||||||
const release = await Logger.safeExecute(
|
const release = await safeExecute(
|
||||||
() => getLatestReleaseWithDownloadStatus(),
|
() => getLatestReleaseWithDownloadStatus(),
|
||||||
'Failed to load latest release:'
|
'Failed to load latest release:'
|
||||||
);
|
);
|
||||||
|
|
@ -174,7 +174,7 @@ export const VersionsTab = () => {
|
||||||
}, [downloading]);
|
}, [downloading]);
|
||||||
|
|
||||||
const handleDownload = async (version: VersionInfo) => {
|
const handleDownload = async (version: VersionInfo) => {
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
const download = availableDownloads.find((d) => d.name === version.name);
|
const download = availableDownloads.find((d) => d.name === version.name);
|
||||||
if (!download) {
|
if (!download) {
|
||||||
throw new Error('Download not found');
|
throw new Error('Download not found');
|
||||||
|
|
@ -193,7 +193,7 @@ export const VersionsTab = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdate = async (version: VersionInfo) => {
|
const handleUpdate = async (version: VersionInfo) => {
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
const download = availableDownloads.find((d) => d.name === version.name);
|
const download = availableDownloads.find((d) => d.name === version.name);
|
||||||
if (!download) {
|
if (!download) {
|
||||||
throw new Error('Download not found');
|
throw new Error('Download not found');
|
||||||
|
|
@ -214,7 +214,7 @@ export const VersionsTab = () => {
|
||||||
const makeCurrent = async (version: VersionInfo) => {
|
const makeCurrent = async (version: VersionInfo) => {
|
||||||
if (!version.installedPath) return;
|
if (!version.installedPath) return;
|
||||||
|
|
||||||
await Logger.safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
const success = await window.electronAPI.kobold.setCurrentVersion(
|
const success = await window.electronAPI.kobold.setCurrentVersion(
|
||||||
version.installedPath!
|
version.installedPath!
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { useState, useCallback, useEffect } from 'react';
|
import { useState, useCallback, useEffect } from 'react';
|
||||||
|
import { error } from '@/utils/logger';
|
||||||
import { compareVersions } from '@/utils/version';
|
import { compareVersions } from '@/utils/version';
|
||||||
import { GITHUB_API } from '@/constants';
|
import { GITHUB_API } from '@/constants';
|
||||||
|
|
||||||
|
|
@ -48,11 +49,8 @@ export const useAppUpdateChecker = () => {
|
||||||
setLastChecked(new Date());
|
setLastChecked(new Date());
|
||||||
|
|
||||||
return updateInfo;
|
return updateInfo;
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError(
|
error('Failed to check for app updates:', err as Error);
|
||||||
'Failed to check for app updates:',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
} finally {
|
} finally {
|
||||||
setIsChecking(false);
|
setIsChecking(false);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
|
import { error } from '@/utils/logger';
|
||||||
import { getROCmDownload } from '@/utils/rocm';
|
import { getROCmDownload } from '@/utils/rocm';
|
||||||
import { GITHUB_API } from '@/constants';
|
import { GITHUB_API } from '@/constants';
|
||||||
import { filterAssetsByPlatform } from '@/utils/platform';
|
import { filterAssetsByPlatform } from '@/utils/platform';
|
||||||
|
|
@ -45,11 +46,8 @@ const saveToCache = (releases: DownloadItem[]) => {
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
};
|
};
|
||||||
localStorage.setItem(CACHE_KEY, JSON.stringify(data));
|
localStorage.setItem(CACHE_KEY, JSON.stringify(data));
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError(
|
error('Failed to save releases to cache', err as Error);
|
||||||
'Failed to save releases to cache',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -126,11 +124,8 @@ const getLatestReleaseWithDownloadStatus =
|
||||||
release: latestRelease,
|
release: latestRelease,
|
||||||
availableAssets,
|
availableAssets,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError(
|
error('Failed to fetch latest release with status:', err as Error);
|
||||||
'Failed to fetch latest release with status:',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -209,12 +204,8 @@ export const useKoboldVersions = (): UseKoboldVersionsReturn => {
|
||||||
}
|
}
|
||||||
|
|
||||||
setAvailableDownloads(allDownloads);
|
setAvailableDownloads(allDownloads);
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError(
|
error('Failed to load remote versions:', err as Error);
|
||||||
'Failed to load remote versions:',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
|
|
||||||
const cached = loadFromCache();
|
const cached = loadFromCache();
|
||||||
if (cached) {
|
if (cached) {
|
||||||
const rocm = await getROCmDownload().catch(() => null);
|
const rocm = await getROCmDownload().catch(() => null);
|
||||||
|
|
@ -251,11 +242,8 @@ export const useKoboldVersions = (): UseKoboldVersionsReturn => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.success !== false;
|
return result.success !== false;
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError(
|
error('Failed to download ${item.name}:', err as Error);
|
||||||
`Failed to download ${item.name}:`,
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
setDownloading(null);
|
setDownloading(null);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback } from 'react';
|
||||||
|
import { error } from '@/utils/logger';
|
||||||
import type { SdConvDirectMode } from '@/types';
|
import type { SdConvDirectMode } from '@/types';
|
||||||
|
|
||||||
interface UseLaunchLogicProps {
|
interface UseLaunchLogicProps {
|
||||||
|
|
@ -285,11 +286,8 @@ export const useLaunchLogic = ({
|
||||||
new Error(errorMessage)
|
new Error(errorMessage)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError(
|
error('Error launching KoboldCpp:', err as Error);
|
||||||
'Error launching KoboldCpp:',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsLaunching(false);
|
setIsLaunching(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { useState, useCallback, useEffect } from 'react';
|
import { useState, useCallback, useEffect } from 'react';
|
||||||
|
import { error } from '@/utils/logger';
|
||||||
import {
|
import {
|
||||||
getDisplayNameFromPath,
|
getDisplayNameFromPath,
|
||||||
compareVersions,
|
compareVersions,
|
||||||
|
|
@ -34,11 +35,8 @@ export const useUpdateChecker = () => {
|
||||||
setDismissedUpdates(new Set(dismissed));
|
setDismissedUpdates(new Set(dismissed));
|
||||||
}
|
}
|
||||||
setDismissedUpdatesLoaded(true);
|
setDismissedUpdatesLoaded(true);
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError(
|
error('Failed to load dismissed updates:', err as Error);
|
||||||
'Failed to load dismissed updates:',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
setDismissedUpdatesLoaded(true);
|
setDismissedUpdatesLoaded(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -52,11 +50,8 @@ export const useUpdateChecker = () => {
|
||||||
'dismissedUpdates',
|
'dismissedUpdates',
|
||||||
Array.from(updates)
|
Array.from(updates)
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError(
|
error('Failed to save dismissed updates:', err as Error);
|
||||||
'Failed to save dismissed updates:',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
@ -110,11 +105,8 @@ export const useUpdateChecker = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError(
|
error('Failed to check for updates:', err as Error);
|
||||||
'Failed to check for updates:',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsChecking(false);
|
setIsChecking(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { useMemo, useEffect, useState, useCallback } from 'react';
|
import { useMemo, useEffect, useState, useCallback } from 'react';
|
||||||
|
import { safeExecute } from '@/utils/logger';
|
||||||
import type { BackendOption } from '@/types';
|
import type { BackendOption } from '@/types';
|
||||||
|
|
||||||
export interface Warning {
|
export interface Warning {
|
||||||
|
|
@ -100,8 +101,12 @@ const checkVramWarnings = async (backend: string): Promise<Warning[]> => {
|
||||||
const isGpuBackend = ['cuda', 'rocm', 'vulkan', 'clblast'].includes(backend);
|
const isGpuBackend = ['cuda', 'rocm', 'vulkan', 'clblast'].includes(backend);
|
||||||
|
|
||||||
if (isGpuBackend) {
|
if (isGpuBackend) {
|
||||||
try {
|
const gpuMemoryInfo = await safeExecute(
|
||||||
const gpuMemoryInfo = await window.electronAPI.kobold.detectGPUMemory();
|
() => window.electronAPI.kobold.detectGPUMemory(),
|
||||||
|
'Failed to detect GPU memory:'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (gpuMemoryInfo) {
|
||||||
const lowVramGpus = gpuMemoryInfo.filter(
|
const lowVramGpus = gpuMemoryInfo.filter(
|
||||||
(gpu) =>
|
(gpu) =>
|
||||||
typeof gpu.totalMemoryMB === 'number' && gpu.totalMemoryMB < 8192
|
typeof gpu.totalMemoryMB === 'number' && gpu.totalMemoryMB < 8192
|
||||||
|
|
@ -120,11 +125,6 @@ const checkVramWarnings = async (backend: string): Promise<Warning[]> => {
|
||||||
)}). Consider using smaller models, reducing GPU layers, or enabling the "Low VRAM" option on the Advanced tab.`,
|
)}). Consider using smaller models, reducing GPU layers, or enabling the "Low VRAM" option on the Advanced tab.`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
window.electronAPI.logs.logError(
|
|
||||||
'Failed to detect GPU memory:',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,7 +186,7 @@ const checkBackendWarnings = async (params?: {
|
||||||
}): Promise<Warning[]> => {
|
}): Promise<Warning[]> => {
|
||||||
const warnings: Warning[] = [];
|
const warnings: Warning[] = [];
|
||||||
|
|
||||||
try {
|
const result = await safeExecute(async () => {
|
||||||
const [backendSupport, gpuCapabilities, gpuInfo] = await Promise.all([
|
const [backendSupport, gpuCapabilities, gpuInfo] = await Promise.all([
|
||||||
window.electronAPI.kobold.detectBackendSupport(),
|
window.electronAPI.kobold.detectBackendSupport(),
|
||||||
window.electronAPI.kobold.detectGPUCapabilities(),
|
window.electronAPI.kobold.detectGPUCapabilities(),
|
||||||
|
|
@ -224,13 +224,9 @@ const checkBackendWarnings = async (params?: {
|
||||||
}
|
}
|
||||||
|
|
||||||
return warnings;
|
return warnings;
|
||||||
} catch (error) {
|
}, 'Failed to check backend warnings:');
|
||||||
window.electronAPI.logs.logError(
|
|
||||||
'Failed to check backend warnings:',
|
return result || warnings;
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
return warnings;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useWarnings = ({
|
export const useWarnings = ({
|
||||||
|
|
@ -254,7 +250,7 @@ export const useWarnings = ({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
const result = await safeExecute(async () => {
|
||||||
const [cpuCapabilitiesResult, availableBackends] = await Promise.all([
|
const [cpuCapabilitiesResult, availableBackends] = await Promise.all([
|
||||||
window.electronAPI.kobold.detectCPU(),
|
window.electronAPI.kobold.detectCPU(),
|
||||||
window.electronAPI.kobold.getAvailableBackends(),
|
window.electronAPI.kobold.getAvailableBackends(),
|
||||||
|
|
@ -265,21 +261,16 @@ export const useWarnings = ({
|
||||||
avx2: cpuCapabilitiesResult.avx2,
|
avx2: cpuCapabilitiesResult.avx2,
|
||||||
};
|
};
|
||||||
|
|
||||||
const warnings = await checkBackendWarnings({
|
return checkBackendWarnings({
|
||||||
backend,
|
backend,
|
||||||
cpuCapabilities,
|
cpuCapabilities,
|
||||||
noavx2,
|
noavx2,
|
||||||
failsafe,
|
failsafe,
|
||||||
availableBackends,
|
availableBackends,
|
||||||
});
|
});
|
||||||
setBackendWarnings(warnings);
|
}, 'Failed to check backend warnings:');
|
||||||
} catch (error) {
|
|
||||||
window.electronAPI.logs.logError(
|
setBackendWarnings(result || []);
|
||||||
'Failed to check backend warnings:',
|
|
||||||
error as Error
|
|
||||||
);
|
|
||||||
setBackendWarnings([]);
|
|
||||||
}
|
|
||||||
}, [backend, noavx2, failsafe]);
|
}, [backend, noavx2, failsafe]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ export class WindowManager {
|
||||||
private setupContextMenu() {
|
private setupContextMenu() {
|
||||||
if (!this.mainWindow) return;
|
if (!this.mainWindow) return;
|
||||||
|
|
||||||
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
this.mainWindow.webContents.on('context-menu', (_, params) => {
|
this.mainWindow.webContents.on('context-menu', (_, params) => {
|
||||||
const hasLinkURL = !!params.linkURL;
|
const hasLinkURL = !!params.linkURL;
|
||||||
const hasSelection = !!params.selectionText;
|
const hasSelection = !!params.selectionText;
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,54 @@
|
||||||
export class Logger {
|
const logError = (message: string, error: Error): void => {
|
||||||
private static logError(message: string, error: Error): void {
|
if (window.electronAPI?.logs?.logError) {
|
||||||
if (window.electronAPI?.logs?.logError) {
|
window.electronAPI.logs.logError(message, error);
|
||||||
window.electronAPI.logs.logError(message, error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static async safeExecute<T>(
|
export const safeExecute = async <T>(
|
||||||
operation: () => Promise<T>,
|
operation: () => Promise<T>,
|
||||||
errorMessage: string
|
errorMessage: string
|
||||||
): Promise<T | null> {
|
): Promise<T | null> => {
|
||||||
try {
|
try {
|
||||||
return operation();
|
return operation();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logError(errorMessage, error as Error);
|
logError(errorMessage, error as Error);
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static safeExecuteSync<T>(
|
export const safeExecuteSync = <T>(
|
||||||
operation: () => T,
|
operation: () => T,
|
||||||
errorMessage: string
|
errorMessage: string
|
||||||
): T | null {
|
): T | null => {
|
||||||
try {
|
try {
|
||||||
return operation();
|
return operation();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logError(errorMessage, error as Error);
|
logError(errorMessage, error as Error);
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static async tryExecute(
|
export const tryExecute = async (
|
||||||
operation: () => Promise<void>,
|
operation: () => Promise<void>,
|
||||||
errorMessage: string
|
errorMessage: string
|
||||||
): Promise<boolean> {
|
): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
await operation();
|
await operation();
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logError(errorMessage, error as Error);
|
logError(errorMessage, error as Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static withErrorHandling<TArgs extends unknown[], TReturn>(
|
export const withErrorHandling =
|
||||||
|
<TArgs extends unknown[], TReturn>(
|
||||||
fn: (...args: TArgs) => Promise<TReturn>,
|
fn: (...args: TArgs) => Promise<TReturn>,
|
||||||
errorMessage: string
|
errorMessage: string
|
||||||
): (...args: TArgs) => Promise<TReturn | null> {
|
): ((...args: TArgs) => Promise<TReturn | null>) =>
|
||||||
return async (...args: TArgs) =>
|
async (...args: TArgs) =>
|
||||||
this.safeExecute(() => fn(...args), errorMessage);
|
safeExecute(() => fn(...args), errorMessage);
|
||||||
}
|
|
||||||
|
|
||||||
static error(message: string, error: Error): void {
|
export const error = (message: string, error: Error): void => {
|
||||||
this.logError(message, error);
|
logError(message, error);
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { error } from '@/utils/logger';
|
||||||
|
|
||||||
export const handleTerminalOutput = (
|
export const handleTerminalOutput = (
|
||||||
prevContent: string,
|
prevContent: string,
|
||||||
newData: string
|
newData: string
|
||||||
|
|
@ -19,8 +21,8 @@ export const handleTerminalOutput = (
|
||||||
}
|
}
|
||||||
|
|
||||||
return prevContent + newData;
|
return prevContent + newData;
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
window.electronAPI.logs.logError('Terminal Basic Error', error as Error);
|
error('Terminal Basic Error', err as Error);
|
||||||
return prevContent + newData;
|
return prevContent + newData;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue