Use errorMessage (#6749)
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -419,7 +419,7 @@ export function AppInner() {
|
||||
} catch (error) {
|
||||
console.error('Error sending reactReady:', error);
|
||||
setFatalError(
|
||||
`React ready notification failed: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
`React ready notification failed: ${errorMessage(error, 'Unknown error')}`
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
@@ -445,7 +445,7 @@ export function AppInner() {
|
||||
const shareToken = link.replace('goose://sessions/', '');
|
||||
const options = {
|
||||
sessionDetails: null,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
error: errorMessage(error, 'Unknown error'),
|
||||
shareToken,
|
||||
};
|
||||
navigate('/shared-session', { state: options });
|
||||
|
||||
@@ -15,6 +15,7 @@ import type { ExtensionConfig } from '../api/types.gen';
|
||||
import { View, ViewOptions } from '../utils/navigationUtils';
|
||||
import { useConfig } from './ConfigContext';
|
||||
import { toastService } from '../toasts';
|
||||
import { errorMessage } from '../utils/conversionUtils';
|
||||
|
||||
type ModalType = 'blocked' | 'untrusted' | 'trusted';
|
||||
|
||||
@@ -208,7 +209,7 @@ export function ExtensionInstallModal({ addExtension, setView }: ExtensionInstal
|
||||
console.error('Error processing extension request:', error);
|
||||
setModalState((prev) => ({
|
||||
...prev,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
error: errorMessage(error, 'Unknown error'),
|
||||
}));
|
||||
} finally {
|
||||
processingLinkRef.current = null;
|
||||
@@ -248,16 +249,11 @@ export function ExtensionInstallModal({ addExtension, setView }: ExtensionInstal
|
||||
} else {
|
||||
throw new Error('addExtension function not provided to component');
|
||||
}
|
||||
|
||||
// Only dismiss modal after successful installation
|
||||
dismissModal();
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : 'Installation failed';
|
||||
console.error('Extension installation failed:', error);
|
||||
|
||||
setModalState((prev) => ({
|
||||
...prev,
|
||||
error: errorMessage,
|
||||
error: errorMessage(error, 'Installation failed'),
|
||||
isPending: false,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useState, useEffect } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { EmbeddedResource } from '../api';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
import { errorMessage } from '../utils/conversionUtils';
|
||||
|
||||
interface MCPUIResourceRendererProps {
|
||||
content: EmbeddedResource & { type: 'resource' };
|
||||
@@ -154,7 +155,7 @@ export default function MCPUIResourceRenderer({
|
||||
error: {
|
||||
code: UIActionErrorCode.PROMPT_FAILED,
|
||||
message: 'Failed to send prompt to chat',
|
||||
details: error instanceof Error ? error.message : error,
|
||||
details: errorMessage(error),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -218,7 +219,7 @@ export default function MCPUIResourceRenderer({
|
||||
error: {
|
||||
code: UIActionErrorCode.NAVIGATION_FAILED,
|
||||
message: `Unexpected error opening URL: ${url}`,
|
||||
details: error instanceof Error ? error.message : error,
|
||||
details: errorMessage(error),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
import { cn } from '../../utils';
|
||||
import { DEFAULT_IFRAME_HEIGHT } from './utils';
|
||||
import { readResource, callTool } from '../../api';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
|
||||
interface McpAppRendererProps {
|
||||
resourceUri: string;
|
||||
@@ -92,7 +93,7 @@ export default function McpAppRenderer({
|
||||
}
|
||||
} catch (err) {
|
||||
if (!cachedHtml) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to load resource');
|
||||
setError(errorMessage(err, 'Failed to load resource'));
|
||||
} else {
|
||||
console.warn('Failed to fetch fresh resource, using cached version:', err);
|
||||
}
|
||||
|
||||
@@ -3,15 +3,13 @@ import { toastError, toastSuccess } from '../toasts';
|
||||
import Model, { getProviderMetadata } from './settings/models/modelInterface';
|
||||
import { ProviderMetadata, setConfigProvider, updateAgentProvider } from '../api';
|
||||
import { useConfig } from './ConfigContext';
|
||||
import { errorMessage } from '../utils/conversionUtils';
|
||||
import {
|
||||
getModelDisplayName,
|
||||
getProviderDisplayName,
|
||||
} from './settings/models/predefinedModelsUtils';
|
||||
|
||||
// titles
|
||||
export const UNKNOWN_PROVIDER_TITLE = 'Provider name lookup';
|
||||
|
||||
// errors
|
||||
export const UNKNOWN_PROVIDER_MSG = 'Unknown provider in config -- please inspect your config.yaml';
|
||||
|
||||
// success
|
||||
@@ -80,7 +78,7 @@ export const ModelAndProviderProvider: React.FC<ModelAndProviderProviderProps> =
|
||||
toastError({
|
||||
title: `${providerName}/${modelName} failed`,
|
||||
msg: `${error}`,
|
||||
traceback: error instanceof Error ? error.message : String(error),
|
||||
traceback: errorMessage(error),
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -9,9 +9,9 @@ import {
|
||||
getPreferredModel,
|
||||
type PullProgress,
|
||||
} from '../utils/ollamaDetection';
|
||||
//import { initializeSystem } from '../utils/providerUtils';
|
||||
import { toastService } from '../toasts';
|
||||
import { Ollama } from './icons';
|
||||
import { errorMessage } from '../utils/conversionUtils';
|
||||
|
||||
interface OllamaSetupProps {
|
||||
onSuccess: () => void;
|
||||
@@ -120,7 +120,7 @@ export function OllamaSetup({ onSuccess, onCancel }: OllamaSetupProps) {
|
||||
console.error('Failed to connect to Ollama:', error);
|
||||
toastService.error({
|
||||
title: 'Connection Failed',
|
||||
msg: `Failed to connect to Ollama: ${error instanceof Error ? error.message : String(error)}`,
|
||||
msg: `Failed to connect to Ollama: ${errorMessage(error)}`,
|
||||
traceback: error instanceof Error ? error.stack || '' : '',
|
||||
});
|
||||
setIsConnecting(false);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
|
||||
import { IoIosCloseCircle, IoIosWarning, IoIosInformationCircle } from 'react-icons/io';
|
||||
import { FaPencilAlt, FaSave } from 'react-icons/fa';
|
||||
import { cn } from '../../utils';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
import { Alert, AlertType } from './types';
|
||||
import { upsertConfig } from '../../api';
|
||||
import { useConfig } from '../ConfigContext';
|
||||
@@ -90,7 +91,7 @@ export const AlertBox = ({ alert, className }: AlertBoxProps) => {
|
||||
} catch (error) {
|
||||
console.error('Error saving threshold:', error);
|
||||
window.alert(
|
||||
`Failed to save threshold: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
`Failed to save threshold: ${errorMessage(error, 'Unknown error')}`
|
||||
);
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Download, Play, Upload } from 'lucide-react';
|
||||
import { exportApp, GooseApp, importApp, listApps } from '../../api';
|
||||
import { useChatContext } from '../../contexts/ChatContext';
|
||||
import { formatAppName } from '../../utils/conversionUtils';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
|
||||
const GridLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
@@ -63,7 +64,7 @@ export default function AppsView() {
|
||||
console.warn('Failed to refresh apps:', err);
|
||||
// Don't set error if we already have cached apps
|
||||
if (apps.length === 0) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to load apps');
|
||||
setError(errorMessage(err, 'Failed to load apps'));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -115,7 +116,7 @@ export default function AppsView() {
|
||||
} catch (err) {
|
||||
// Only set error if we don't have apps to show
|
||||
if (apps.length === 0) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to load apps');
|
||||
setError(errorMessage(err, 'Failed to load apps'));
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@@ -151,7 +152,7 @@ export default function AppsView() {
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to export app:', err);
|
||||
setError(err instanceof Error ? err.message : 'Failed to export app');
|
||||
setError(errorMessage(err, 'Failed to export app'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -179,7 +180,7 @@ export default function AppsView() {
|
||||
setError(null);
|
||||
} catch (err) {
|
||||
console.error('Failed to import app:', err);
|
||||
setError(err instanceof Error ? err.message : 'Failed to import app');
|
||||
setError(errorMessage(err, 'Failed to import app'));
|
||||
}
|
||||
event.target.value = '';
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useSearchParams } from 'react-router-dom';
|
||||
import McpAppRenderer from '../McpApps/McpAppRenderer';
|
||||
import { startAgent, resumeAgent, listApps, stopAgent } from '../../api';
|
||||
import { formatAppName } from '../../utils/conversionUtils';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
|
||||
export default function StandaloneAppView() {
|
||||
const [searchParams] = useSearchParams();
|
||||
@@ -78,7 +79,7 @@ export default function StandaloneAppView() {
|
||||
} catch (err) {
|
||||
console.error('Failed to initialize session:', err);
|
||||
if (!cachedHtml) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to initialize session');
|
||||
setError(errorMessage(err, 'Failed to initialize session'));
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { RecipeFormFields } from './shared/RecipeFormFields';
|
||||
import { RecipeFormData } from './shared/recipeFormSchema';
|
||||
import { toastSuccess, toastError } from '../../toasts';
|
||||
import { saveRecipe } from '../../recipe/recipe_management';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
|
||||
interface CreateEditRecipeModalProps {
|
||||
isOpen: boolean;
|
||||
@@ -272,8 +273,8 @@ export default function CreateEditRecipeModal({
|
||||
|
||||
toastError({
|
||||
title: 'Save Failed',
|
||||
msg: `Failed to save recipe: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
traceback: error instanceof Error ? error.message : String(error),
|
||||
msg: `Failed to save recipe: ${errorMessage(error, 'Unknown error')}`,
|
||||
traceback: errorMessage(error),
|
||||
});
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
@@ -317,8 +318,8 @@ export default function CreateEditRecipeModal({
|
||||
|
||||
toastError({
|
||||
title: 'Save and Run Failed',
|
||||
msg: `Failed to save and run recipe: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
traceback: error instanceof Error ? error.message : String(error),
|
||||
msg: `Failed to save and run recipe: ${errorMessage(error, 'Unknown error')}`,
|
||||
traceback: errorMessage(error),
|
||||
});
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
|
||||
@@ -10,6 +10,7 @@ import { createRecipe } from '../../api/sdk.gen';
|
||||
import { RecipeParameter } from './shared/recipeFormSchema';
|
||||
import { toastError } from '../../toasts';
|
||||
import { saveRecipe } from '../../recipe/recipe_management';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
|
||||
interface CreateRecipeFromSessionModalProps {
|
||||
isOpen: boolean;
|
||||
@@ -202,10 +203,10 @@ export default function CreateRecipeFromSessionModal({
|
||||
console.error('Failed to create recipe:', error);
|
||||
toastError({
|
||||
title: 'Failed to create recipe',
|
||||
msg:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: 'An unexpected error occurred while creating the recipe. Please try again.',
|
||||
msg: errorMessage(
|
||||
error,
|
||||
'An unexpected error occurred while creating the recipe. Please try again.'
|
||||
),
|
||||
});
|
||||
} finally {
|
||||
setIsCreating(false);
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useEscapeKey } from '../../hooks/useEscapeKey';
|
||||
import { getRecipeJsonSchema } from '../../recipe/validation';
|
||||
import { saveRecipe } from '../../recipe/recipe_management';
|
||||
import { parseRecipe } from '../../api';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
|
||||
interface ImportRecipeFormProps {
|
||||
isOpen: boolean;
|
||||
@@ -138,8 +139,8 @@ export default function ImportRecipeForm({ isOpen, onClose, onSuccess }: ImportR
|
||||
|
||||
toastError({
|
||||
title: 'Import Failed',
|
||||
msg: `Failed to import recipe: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
traceback: error instanceof Error ? error.message : String(error),
|
||||
msg: `Failed to import recipe: ${errorMessage(error, 'Unknown error')}`,
|
||||
traceback: errorMessage(error),
|
||||
});
|
||||
} finally {
|
||||
setImporting(false);
|
||||
@@ -167,7 +168,7 @@ export default function ImportRecipeForm({ isOpen, onClose, onSuccess }: ImportR
|
||||
} catch (error) {
|
||||
toastError({
|
||||
title: 'Invalid Deeplink',
|
||||
msg: `The deeplink format is invalid: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
msg: `The deeplink format is invalid: ${errorMessage(error, 'Unknown error')}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -183,7 +184,7 @@ export default function ImportRecipeForm({ isOpen, onClose, onSuccess }: ImportR
|
||||
} catch (error) {
|
||||
toastError({
|
||||
title: 'Invalid Recipe File',
|
||||
msg: error instanceof Error ? error.message : 'Unknown error',
|
||||
msg: errorMessage(error, 'Unknown error'),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ import {
|
||||
DropdownMenuSeparator,
|
||||
} from '../ui/dropdown-menu';
|
||||
import { getSearchShortcutText } from '../../utils/keyboardShortcuts';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
|
||||
export default function RecipesView() {
|
||||
const setView = useNavigation();
|
||||
@@ -130,7 +131,7 @@ export default function RecipesView() {
|
||||
const recipeManifestResponses = await listSavedRecipes();
|
||||
setSavedRecipes(recipeManifestResponses);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to load recipes');
|
||||
setError(errorMessage(err, 'Failed to load recipes'));
|
||||
console.error('Failed to load saved recipes:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@@ -154,7 +155,7 @@ export default function RecipesView() {
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to load recipe:', error);
|
||||
const errorMsg = error instanceof Error ? error.message : 'Failed to load recipe';
|
||||
const errorMsg = errorMessage(error, 'Failed to load recipe');
|
||||
trackRecipeStarted(false, getErrorType(error), false);
|
||||
setError(errorMsg);
|
||||
}
|
||||
@@ -201,7 +202,7 @@ export default function RecipesView() {
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to delete recipe:', err);
|
||||
const errorMsg = err instanceof Error ? err.message : 'Failed to delete recipe';
|
||||
const errorMsg = errorMessage(err, 'Failed to delete recipe');
|
||||
trackRecipeDeleted(false, getErrorType(err));
|
||||
setError(errorMsg);
|
||||
}
|
||||
@@ -341,7 +342,7 @@ export default function RecipesView() {
|
||||
await loadSavedRecipes();
|
||||
} catch (error) {
|
||||
console.error('Failed to save schedule:', error);
|
||||
const errorMsg = error instanceof Error ? error.message : 'Failed to save schedule';
|
||||
const errorMsg = errorMessage(error, 'Failed to save schedule');
|
||||
trackRecipeScheduled(false, action, getErrorType(error));
|
||||
setError(errorMsg);
|
||||
}
|
||||
@@ -369,7 +370,7 @@ export default function RecipesView() {
|
||||
await loadSavedRecipes();
|
||||
} catch (error) {
|
||||
console.error('Failed to remove schedule:', error);
|
||||
const errorMsg = error instanceof Error ? error.message : 'Failed to remove schedule';
|
||||
const errorMsg = errorMessage(error, 'Failed to remove schedule');
|
||||
trackRecipeScheduled(false, 'remove', getErrorType(error));
|
||||
setError(errorMsg);
|
||||
}
|
||||
@@ -409,7 +410,7 @@ export default function RecipesView() {
|
||||
await loadSavedRecipes();
|
||||
} catch (error) {
|
||||
console.error('Failed to save slash command:', error);
|
||||
const errorMsg = error instanceof Error ? error.message : 'Failed to save slash command';
|
||||
const errorMsg = errorMessage(error, 'Failed to save slash command');
|
||||
trackRecipeSlashCommandSet(false, action, getErrorType(error));
|
||||
setError(errorMsg);
|
||||
}
|
||||
@@ -437,7 +438,7 @@ export default function RecipesView() {
|
||||
await loadSavedRecipes();
|
||||
} catch (error) {
|
||||
console.error('Failed to remove slash command:', error);
|
||||
const errorMsg = error instanceof Error ? error.message : 'Failed to remove slash command';
|
||||
const errorMsg = errorMessage(error, 'Failed to remove slash command');
|
||||
trackRecipeSlashCommandSet(false, 'remove', getErrorType(error));
|
||||
setError(errorMsg);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import cronstrue from 'cronstrue';
|
||||
import { formatToLocalDateWithTimezone } from '../../utils/date';
|
||||
import { getSession, Session } from '../../api';
|
||||
import { trackScheduleRunNow, getErrorType } from '../../utils/analytics';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
|
||||
interface ScheduleSessionMeta {
|
||||
id: string;
|
||||
@@ -67,7 +68,7 @@ const ScheduleDetailView: React.FC<ScheduleDetailViewProps> = ({ scheduleId, onN
|
||||
const data = await getScheduleSessions(sId, 20);
|
||||
setSessions(data);
|
||||
} catch (err) {
|
||||
setSessionsError(err instanceof Error ? err.message : 'Failed to fetch sessions');
|
||||
setSessionsError(errorMessage(err, 'Failed to fetch sessions'));
|
||||
} finally {
|
||||
setIsLoadingSessions(false);
|
||||
}
|
||||
@@ -85,7 +86,7 @@ const ScheduleDetailView: React.FC<ScheduleDetailViewProps> = ({ scheduleId, onN
|
||||
setScheduleError('Schedule not found');
|
||||
}
|
||||
} catch (err) {
|
||||
setScheduleError(err instanceof Error ? err.message : 'Failed to fetch schedule');
|
||||
setScheduleError(errorMessage(err, 'Failed to fetch schedule'));
|
||||
} finally {
|
||||
setIsLoadingSchedule(false);
|
||||
}
|
||||
@@ -112,7 +113,7 @@ const ScheduleDetailView: React.FC<ScheduleDetailViewProps> = ({ scheduleId, onN
|
||||
await fetchSessions(scheduleId);
|
||||
await fetchSchedule(scheduleId);
|
||||
} catch (err) {
|
||||
const errorMsg = err instanceof Error ? err.message : 'Failed to trigger schedule';
|
||||
const errorMsg = errorMessage(err, 'Failed to trigger schedule');
|
||||
trackScheduleRunNow(false, getErrorType(err));
|
||||
toastError({
|
||||
title: 'Run Schedule Error',
|
||||
@@ -136,7 +137,7 @@ const ScheduleDetailView: React.FC<ScheduleDetailViewProps> = ({ scheduleId, onN
|
||||
}
|
||||
await fetchSchedule(scheduleId);
|
||||
} catch (err) {
|
||||
const errorMsg = err instanceof Error ? err.message : 'Operation failed';
|
||||
const errorMsg = errorMessage(err, 'Operation failed');
|
||||
toastError({
|
||||
title: 'Pause/Unpause Error',
|
||||
msg: errorMsg,
|
||||
@@ -154,7 +155,7 @@ const ScheduleDetailView: React.FC<ScheduleDetailViewProps> = ({ scheduleId, onN
|
||||
toastSuccess({ title: 'Job Killed', msg: result.message });
|
||||
await fetchSchedule(scheduleId);
|
||||
} catch (err) {
|
||||
const errorMsg = err instanceof Error ? err.message : 'Failed to kill job';
|
||||
const errorMsg = errorMessage(err, 'Failed to kill job');
|
||||
toastError({
|
||||
title: 'Kill Job Error',
|
||||
msg: errorMsg,
|
||||
@@ -181,7 +182,7 @@ const ScheduleDetailView: React.FC<ScheduleDetailViewProps> = ({ scheduleId, onN
|
||||
toastSuccess({ title: 'Job Inspection', msg: 'No detailed information available' });
|
||||
}
|
||||
} catch (err) {
|
||||
const errorMsg = err instanceof Error ? err.message : 'Failed to inspect job';
|
||||
const errorMsg = errorMessage(err, 'Failed to inspect job');
|
||||
toastError({
|
||||
title: 'Inspect Job Error',
|
||||
msg: errorMsg,
|
||||
@@ -200,7 +201,7 @@ const ScheduleDetailView: React.FC<ScheduleDetailViewProps> = ({ scheduleId, onN
|
||||
await fetchSchedule(scheduleId);
|
||||
setIsModalOpen(false);
|
||||
} catch (err) {
|
||||
const errorMsg = err instanceof Error ? err.message : 'Failed to update schedule';
|
||||
const errorMsg = errorMessage(err, 'Failed to update schedule');
|
||||
toastError({
|
||||
title: 'Update Schedule Error',
|
||||
msg: errorMsg,
|
||||
@@ -220,7 +221,7 @@ const ScheduleDetailView: React.FC<ScheduleDetailViewProps> = ({ scheduleId, onN
|
||||
});
|
||||
setSelectedSession(response.data);
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : 'Failed to load session';
|
||||
const msg = errorMessage(err, 'Failed to load session');
|
||||
setSessionError(msg);
|
||||
toastError({ title: 'Failed to load session', msg });
|
||||
} finally {
|
||||
|
||||
@@ -21,6 +21,7 @@ import ScheduleDetailView from './ScheduleDetailView';
|
||||
import { toastError, toastSuccess } from '../../toasts';
|
||||
import cronstrue from 'cronstrue';
|
||||
import { formatToLocalDateWithTimezone } from '../../utils/date';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
import { MainPanelLayout } from '../Layout/MainPanelLayout';
|
||||
import { ViewOptions } from '../../utils/navigationUtils';
|
||||
import { trackScheduleCreated, trackScheduleDeleted, getErrorType } from '../../utils/analytics';
|
||||
@@ -206,9 +207,7 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose: _onClose }) => {
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch schedules:', error);
|
||||
setApiError(
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: 'An unknown error occurred while fetching schedules.'
|
||||
errorMessage(error, 'An unknown error occurred while fetching schedules.')
|
||||
);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
@@ -270,7 +269,7 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose: _onClose }) => {
|
||||
setEditingSchedule(null);
|
||||
} catch (error) {
|
||||
console.error('Failed to save schedule:', error);
|
||||
const errorMsg = error instanceof Error ? error.message : 'Unknown error saving schedule.';
|
||||
const errorMsg = errorMessage(error, 'Unknown error saving schedule.');
|
||||
setSubmitApiError(errorMsg);
|
||||
|
||||
if (!editingSchedule) {
|
||||
@@ -295,7 +294,7 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose: _onClose }) => {
|
||||
await fetchSchedules();
|
||||
} catch (error) {
|
||||
console.error(`Failed to delete schedule "${id}":`, error);
|
||||
const errorMsg = error instanceof Error ? error.message : `Unknown error deleting "${id}".`;
|
||||
const errorMsg = errorMessage(error, `Unknown error deleting "${id}".`);
|
||||
setApiError(errorMsg);
|
||||
trackScheduleDeleted(false, getErrorType(error));
|
||||
} finally {
|
||||
@@ -320,7 +319,7 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose: _onClose }) => {
|
||||
await fetchSchedules();
|
||||
} catch (error) {
|
||||
console.error(`Failed to pause schedule "${id}":`, error);
|
||||
const errorMsg = error instanceof Error ? error.message : `Unknown error pausing "${id}".`;
|
||||
const errorMsg = errorMessage(error, `Unknown error pausing "${id}".`);
|
||||
setApiError(errorMsg);
|
||||
toastError({
|
||||
title: 'Pause Schedule Error',
|
||||
@@ -348,7 +347,7 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose: _onClose }) => {
|
||||
await fetchSchedules();
|
||||
} catch (error) {
|
||||
console.error(`Failed to unpause schedule "${id}":`, error);
|
||||
const errorMsg = error instanceof Error ? error.message : `Unknown error unpausing "${id}".`;
|
||||
const errorMsg = errorMessage(error, `Unknown error unpausing "${id}".`);
|
||||
setApiError(errorMsg);
|
||||
toastError({
|
||||
title: 'Unpause Schedule Error',
|
||||
@@ -377,7 +376,7 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose: _onClose }) => {
|
||||
} catch (error) {
|
||||
console.error(`Failed to kill running job "${id}":`, error);
|
||||
const errorMsg =
|
||||
error instanceof Error ? error.message : `Unknown error killing job "${id}".`;
|
||||
errorMessage(error, `Unknown error killing job "${id}".`);
|
||||
setApiError(errorMsg);
|
||||
toastError({
|
||||
title: 'Kill Job Error',
|
||||
@@ -415,7 +414,7 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose: _onClose }) => {
|
||||
} catch (error) {
|
||||
console.error(`Failed to inspect running job "${id}":`, error);
|
||||
const errorMsg =
|
||||
error instanceof Error ? error.message : `Unknown error inspecting job "${id}".`;
|
||||
errorMessage(error, `Unknown error inspecting job "${id}".`);
|
||||
setApiError(errorMsg);
|
||||
toastError({
|
||||
title: 'Inspect Job Error',
|
||||
|
||||
@@ -18,6 +18,7 @@ import { MainPanelLayout } from '../Layout/MainPanelLayout';
|
||||
import { ScrollArea } from '../ui/scroll-area';
|
||||
import { formatMessageTimestamp } from '../../utils/timeUtils';
|
||||
import { createSharedSession } from '../../sharedSessions';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@@ -189,7 +190,7 @@ const SessionHistoryView: React.FC<SessionHistoryViewProps> = ({
|
||||
} catch (error) {
|
||||
console.error('Error sharing session:', error);
|
||||
toast.error(
|
||||
`Failed to share session: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
`Failed to share session: ${errorMessage(error, 'Unknown error')}`
|
||||
);
|
||||
} finally {
|
||||
setIsSharing(false);
|
||||
@@ -213,7 +214,7 @@ const SessionHistoryView: React.FC<SessionHistoryViewProps> = ({
|
||||
try {
|
||||
resumeSession(session, setView);
|
||||
} catch (error) {
|
||||
toast.error(`Could not launch session: ${error instanceof Error ? error.message : error}`);
|
||||
toast.error(`Could not launch session: ${errorMessage(error)}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import { SearchView } from '../conversation/SearchView';
|
||||
import { SearchHighlighter } from '../../utils/searchHighlighter';
|
||||
import { MainPanelLayout } from '../Layout/MainPanelLayout';
|
||||
import { groupSessionsByDate, type DateGroup } from '../../utils/dateUtils';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
import { Skeleton } from '../ui/skeleton';
|
||||
import { toast } from 'react-toastify';
|
||||
import { ConfirmationModal } from '../ui/ConfirmationModal';
|
||||
@@ -99,9 +100,9 @@ const EditSessionModal = React.memo<EditSessionModalProps>(
|
||||
toast.success('Session description updated successfully');
|
||||
}, 300);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
||||
console.error('Failed to update session description:', errorMessage);
|
||||
toast.error(`Failed to update session description: ${errorMessage}`);
|
||||
const errMsg = errorMessage(error, 'Unknown error occurred');
|
||||
console.error('Failed to update session description:', errMsg);
|
||||
toast.error(`Failed to update session description: ${errMsg}`);
|
||||
setDescription(session.name);
|
||||
} finally {
|
||||
setIsUpdating(false);
|
||||
@@ -450,8 +451,7 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(
|
||||
await loadSessions();
|
||||
} catch (error) {
|
||||
console.error('Error duplicating session:', error);
|
||||
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||
toast.error(`Failed to duplicate session: ${errorMessage}`);
|
||||
toast.error(`Failed to duplicate session: ${errorMessage(error, 'Unknown error')}`);
|
||||
}
|
||||
},
|
||||
[loadSessions]
|
||||
@@ -476,8 +476,7 @@ const SessionListView: React.FC<SessionListViewProps> = React.memo(
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error deleting session:', error);
|
||||
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||
toast.error(`Failed to delete session "${sessionName}": ${errorMessage}`);
|
||||
toast.error(`Failed to delete session "${sessionName}": ${errorMessage(error, 'Unknown error')}`);
|
||||
}
|
||||
await loadSessions();
|
||||
}, [sessionToDelete, loadSessions]);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
import { Card, CardContent, CardDescription } from '../ui/card';
|
||||
import { Greeting } from '../common/Greeting';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
@@ -34,7 +35,7 @@ export function SessionInsights() {
|
||||
setError(null);
|
||||
} catch (error) {
|
||||
console.error('Failed to load insights:', error);
|
||||
setError(error instanceof Error ? error.message : 'Failed to load insights');
|
||||
setError(errorMessage(error, 'Failed to load insights'));
|
||||
setInsights({
|
||||
totalSessions: 0,
|
||||
totalTokens: 0,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Button } from '../../ui/button';
|
||||
import { Loader2, Download, CheckCircle, AlertCircle } from 'lucide-react';
|
||||
import { errorMessage } from '../../../utils/conversionUtils';
|
||||
|
||||
type UpdateStatus =
|
||||
| 'idle'
|
||||
@@ -154,7 +155,7 @@ export default function UpdateSection() {
|
||||
console.error('Error checking for updates:', error);
|
||||
setUpdateInfo((prev) => ({
|
||||
...prev,
|
||||
error: error instanceof Error ? error.message : 'Failed to check for updates',
|
||||
error: errorMessage(error, 'Failed to check for updates'),
|
||||
}));
|
||||
setUpdateStatus('error');
|
||||
setTimeout(() => setUpdateStatus('idle'), 5000);
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from '../../ui/dialog';
|
||||
import { errorMessage } from '../../../utils/conversionUtils';
|
||||
|
||||
export default function ConfigSettings() {
|
||||
const { config, upsert } = useConfig();
|
||||
@@ -84,7 +85,7 @@ export default function ConfigSettings() {
|
||||
toastError({
|
||||
title: 'Save Failed',
|
||||
msg: `Failed to save "${getUiNames(key)}"`,
|
||||
traceback: error instanceof Error ? error.message : String(error),
|
||||
traceback: errorMessage(error),
|
||||
});
|
||||
} finally {
|
||||
setSaving(null);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ProviderDetails, getProviderModels } from '../../../api';
|
||||
import { errorMessage as getErrorMessage } from '../../../utils/conversionUtils';
|
||||
|
||||
export default interface Model {
|
||||
id?: number; // Make `id` optional to allow user-defined models
|
||||
@@ -60,7 +61,8 @@ export async function fetchModelsForProviders(
|
||||
const models = response.data || [];
|
||||
return { provider: p, models, error: null };
|
||||
} catch (e: unknown) {
|
||||
const errorMessage = `Failed to fetch models for ${p.name}${e instanceof Error ? `: ${e.message}` : ''}`;
|
||||
const errMsg = getErrorMessage(e);
|
||||
const errorMessage = `Failed to fetch models for ${p.name}${errMsg ? `: ${errMsg}` : ''}`;
|
||||
return {
|
||||
provider: p,
|
||||
models: null,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useCallback, useState, useRef, useEffect } from 'react';
|
||||
import { compressImageDataUrl } from '../utils/conversionUtils';
|
||||
import { compressImageDataUrl, errorMessage } from '../utils/conversionUtils';
|
||||
|
||||
export interface DroppedFile {
|
||||
id: string;
|
||||
@@ -66,7 +66,7 @@ export const useFileDrop = () => {
|
||||
type: file.type,
|
||||
isImage: false,
|
||||
isLoading: false,
|
||||
error: `Failed to get file path: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
error: `Failed to get file path: ${errorMessage(error, 'Unknown error')}`,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useConfig } from '../components/ConfigContext';
|
||||
import { getApiUrl } from '../config';
|
||||
import { useDictationSettings } from './useDictationSettings';
|
||||
import { DICTATION_PROVIDER_OPENAI, DICTATION_PROVIDER_ELEVENLABS } from './dictationConstants';
|
||||
import { safeJsonParse } from '../utils/conversionUtils';
|
||||
import { safeJsonParse, errorMessage } from '../utils/conversionUtils';
|
||||
|
||||
interface UseWhisperOptions {
|
||||
onTranscription?: (text: string) => void;
|
||||
@@ -353,8 +353,7 @@ export const useWhisper = ({ onTranscription, onError, onSizeWarning }: UseWhisp
|
||||
setIsRecording(true);
|
||||
} catch (startError) {
|
||||
console.error('Error calling mediaRecorder.start():', startError);
|
||||
const errorMessage = startError instanceof Error ? startError.message : String(startError);
|
||||
throw new Error(`Failed to start recording: ${errorMessage}`);
|
||||
throw new Error(`Failed to start recording: ${errorMessage(startError)}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error starting recording:', error);
|
||||
|
||||
@@ -28,7 +28,7 @@ import { expandTilde } from './utils/pathUtils';
|
||||
import log from './utils/logger';
|
||||
import { ensureWinShims } from './utils/winShims';
|
||||
import { addRecentDir, loadRecentDirs } from './utils/recentDirs';
|
||||
import { formatAppName } from './utils/conversionUtils';
|
||||
import { formatAppName, errorMessage } from './utils/conversionUtils';
|
||||
import type { Settings } from './utils/settings';
|
||||
import { defaultKeyboardShortcuts, getKeyboardShortcuts } from './utils/settings';
|
||||
import * as crypto from 'crypto';
|
||||
@@ -1073,8 +1073,7 @@ function parseRecipeDeeplink(url: string): RecipeDeeplinkData | undefined {
|
||||
try {
|
||||
recipeDeeplink = decodeURIComponent(recipeDeeplinkTmp);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
console.error('[Main] parseRecipeDeeplink - Failed to decode:', errorMessage);
|
||||
console.error('[Main] parseRecipeDeeplink - Failed to decode:', errorMessage(error));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { fetchSharedSessionDetails, SharedSessionDetails } from './sharedSessions';
|
||||
import { View, ViewOptions } from './utils/navigationUtils';
|
||||
import { errorMessage } from './utils/conversionUtils';
|
||||
|
||||
/**
|
||||
* Handles opening a shared session from a deep link
|
||||
@@ -61,13 +62,14 @@ export async function openSharedSessionFromDeepLink(
|
||||
|
||||
return sessionDetails;
|
||||
} catch (error) {
|
||||
const errorMessage = `Failed to open shared session: ${error instanceof Error ? error.message : 'Unknown error'}`;
|
||||
console.error(errorMessage);
|
||||
const errMsg = errorMessage(error, 'Unknown error');
|
||||
const fullErrorMessage = `Failed to open shared session: ${errMsg}`;
|
||||
console.error(fullErrorMessage);
|
||||
|
||||
// Navigate to the shared session view with the error instead of throwing
|
||||
setView('sharedSession', {
|
||||
sessionDetails: null,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
error: errMsg,
|
||||
shareToken: url.replace('goose://sessions/', ''),
|
||||
baseUrl,
|
||||
});
|
||||
|
||||
@@ -16,6 +16,7 @@ import * as fs from 'fs/promises';
|
||||
import log from './logger';
|
||||
import { githubUpdater } from './githubUpdater';
|
||||
import { loadRecentDirs } from './recentDirs';
|
||||
import { errorMessage } from './conversionUtils';
|
||||
import {
|
||||
trackUpdateCheckStarted,
|
||||
trackUpdateCheckCompleted,
|
||||
@@ -99,7 +100,7 @@ export function registerUpdateIpcHandlers() {
|
||||
log.error(`=== MANUAL UPDATE CHECK FAILED after ${duration}ms ===`);
|
||||
log.error('Error checking for updates:', error);
|
||||
log.error('Manual check error details:', {
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
message: errorMessage(error, 'Unknown error'),
|
||||
stack: error instanceof Error ? error.stack : 'No stack',
|
||||
name: error instanceof Error ? error.name : 'Unknown',
|
||||
code:
|
||||
@@ -189,12 +190,12 @@ export function registerUpdateIpcHandlers() {
|
||||
|
||||
trackUpdateCheckCompleted('error', currentVersion, {
|
||||
usingFallback: false,
|
||||
errorType: error instanceof Error ? error.message : 'unknown',
|
||||
errorType: errorMessage(error, 'unknown'),
|
||||
});
|
||||
|
||||
return {
|
||||
updateInfo: null,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
error: errorMessage(error, 'Unknown error'),
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -250,11 +251,11 @@ export function registerUpdateIpcHandlers() {
|
||||
false,
|
||||
version,
|
||||
method,
|
||||
error instanceof Error ? error.message : 'unknown'
|
||||
errorMessage(error, 'unknown')
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
error: errorMessage(error, 'Unknown error'),
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -708,7 +709,7 @@ async function githubAutoDownload(
|
||||
false,
|
||||
latestVersion,
|
||||
'github-fallback',
|
||||
downloadError instanceof Error ? downloadError.message : 'unknown'
|
||||
errorMessage(downloadError, 'unknown')
|
||||
);
|
||||
log.error(
|
||||
`Error during GitHub auto-download${contextLabel ? ` (${contextLabel})` : ''}:`,
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as fs from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import log from './logger';
|
||||
import { safeJsonParse } from './conversionUtils';
|
||||
import { safeJsonParse, errorMessage } from './conversionUtils';
|
||||
|
||||
interface GitHubRelease {
|
||||
tag_name: string;
|
||||
@@ -142,7 +142,7 @@ export class GitHubUpdater {
|
||||
} catch (error) {
|
||||
log.error('GitHubUpdater: Error checking for updates:', error);
|
||||
log.error('GitHubUpdater: Error details:', {
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
message: errorMessage(error, 'Unknown error'),
|
||||
stack: error instanceof Error ? error.stack : 'No stack',
|
||||
name: error instanceof Error ? error.name : 'Unknown',
|
||||
code:
|
||||
@@ -152,7 +152,7 @@ export class GitHubUpdater {
|
||||
});
|
||||
return {
|
||||
updateAvailable: false,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
error: errorMessage(error, 'Unknown error'),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -271,13 +271,13 @@ export class GitHubUpdater {
|
||||
log.error(`=== GitHubUpdater: DOWNLOAD FAILED after ${duration}ms ===`);
|
||||
log.error('GitHubUpdater: Error downloading update:', error);
|
||||
log.error('GitHubUpdater: Download error details:', {
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
message: errorMessage(error, 'Unknown error'),
|
||||
stack: error instanceof Error ? error.stack : 'No stack',
|
||||
name: error instanceof Error ? error.name : 'Unknown',
|
||||
});
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
error: errorMessage(error, 'Unknown error'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { errorMessage } from './conversionUtils';
|
||||
|
||||
const DEFAULT_OLLAMA_HOST = 'http://127.0.0.1:11434';
|
||||
const OLLAMA_DOWNLOAD_URL = 'https://ollama.com/download';
|
||||
const PREFERRED_MODEL = 'gpt-oss:20b';
|
||||
@@ -52,7 +54,7 @@ export async function checkOllamaStatus(): Promise<OllamaStatus> {
|
||||
return {
|
||||
isRunning: false,
|
||||
host: DEFAULT_OLLAMA_HOST,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
error: errorMessage(error, 'Unknown error'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Session } from '../api';
|
||||
import { getApiUrl } from '../config';
|
||||
import { errorMessage } from './conversionUtils';
|
||||
|
||||
/**
|
||||
* In-memory cache for session data
|
||||
@@ -57,10 +58,7 @@ export async function loadSession(sessionId: string, forceRefresh = false): Prom
|
||||
|
||||
return session;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(`Error loading session ${sessionId}: ${error.message}`);
|
||||
}
|
||||
throw new Error(`Error loading session ${sessionId}: Unknown error`);
|
||||
throw new Error(`Error loading session ${sessionId}: ${errorMessage(error, 'Unknown error')}`);
|
||||
} finally {
|
||||
inFlightRequests.delete(sessionId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user