diff --git a/api/utils/axios.js b/api/utils/axios.js index 8b12a5ca9..acd23a184 100644 --- a/api/utils/axios.js +++ b/api/utils/axios.js @@ -5,40 +5,32 @@ const { logger } = require('~/config'); * * @param {Object} options - The options object. * @param {string} options.message - The custom message to be logged. - * @param {Error} options.error - The Axios error object. + * @param {import('axios').AxiosError} options.error - The Axios error object. */ const logAxiosError = ({ message, error }) => { - const timedOutMessage = 'Cannot read properties of undefined (reading \'status\')'; - if (error.response) { - logger.error( - `${message} The request was made and the server responded with a status code that falls out of the range of 2xx: ${ - error.message ? error.message : '' - }. Error response data:\n`, - { - headers: error.response?.headers, - status: error.response?.status, - data: error.response?.data, - }, - ); - } else if (error.request) { - logger.error( - `${message} The request was made but no response was received: ${ - error.message ? error.message : '' - }. Error Request:\n`, - { - request: error.request, - }, - ); - } else if (error?.message?.includes(timedOutMessage)) { - logger.error( - `${message}\nThe request either timed out or was unsuccessful. Error message:\n`, - error, - ); - } else { - logger.error( - `${message}\nSomething happened in setting up the request. Error message:\n`, - error, - ); + try { + if (error.response?.status) { + const { status, headers, data } = error.response; + logger.error(`${message} The server responded with status ${status}: ${error.message}`, { + status, + headers, + data, + }); + } else if (error.request) { + const { method, url } = error.config || {}; + logger.error( + `${message} No response received for ${method ? method.toUpperCase() : ''} ${url || ''}: ${error.message}`, + { requestInfo: { method, url } }, + ); + } else if (error?.message?.includes('Cannot read properties of undefined (reading \'status\')')) { + logger.error( + `${message} It appears the request timed out or was unsuccessful: ${error.message}`, + ); + } else { + logger.error(`${message} An error occurred while setting up the request: ${error.message}`); + } + } catch (err) { + logger.error(`Error in logAxiosError: ${err.message}`); } }; diff --git a/client/src/components/Chat/Input/HeaderOptions.tsx b/client/src/components/Chat/Input/HeaderOptions.tsx index 0bd3326b5..5313f43b8 100644 --- a/client/src/components/Chat/Input/HeaderOptions.tsx +++ b/client/src/components/Chat/Input/HeaderOptions.tsx @@ -1,8 +1,13 @@ import { useRecoilState } from 'recoil'; import { Settings2 } from 'lucide-react'; -import { Root, Anchor } from '@radix-ui/react-popover'; import { useState, useEffect, useMemo } from 'react'; -import { tConvoUpdateSchema, EModelEndpoint, isParamEndpoint } from 'librechat-data-provider'; +import { Root, Anchor } from '@radix-ui/react-popover'; +import { + EModelEndpoint, + isParamEndpoint, + isAgentsEndpoint, + tConvoUpdateSchema, +} from 'librechat-data-provider'; import type { TPreset, TInterfaceConfig } from 'librechat-data-provider'; import { EndpointSettings, SaveAsPresetDialog, AlternativeSettings } from '~/components/Endpoints'; import { PluginStoreDialog, TooltipAnchor } from '~/components'; @@ -42,7 +47,6 @@ export default function HeaderOptions({ if (endpoint && noSettings[endpoint]) { setShowPopover(false); } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [endpoint, noSettings]); const saveAsPreset = () => { @@ -67,7 +71,7 @@ export default function HeaderOptions({
- {interfaceConfig?.modelSelect === true && ( + {interfaceConfig?.modelSelect === true && !isAgentsEndpoint(endpoint) && ( { @@ -20,7 +20,7 @@ const useNavigateToConvo = (index = 0) => { invalidateMessages = false, ) => { if (!conversation) { - console.log('Conversation not provided'); + logger.warn('conversation', 'Conversation not provided to `navigateToConvo`'); return; } hasSetConversation.current = true; @@ -34,10 +34,10 @@ const useNavigateToConvo = (index = 0) => { } let convo = { ...conversation }; - if (!convo.endpoint) { - /* undefined endpoint edge case */ + const endpointsConfig = queryClient.getQueryData([QueryKeys.endpoints]); + if (!convo.endpoint || !endpointsConfig?.[convo.endpoint]) { + /* undefined/removed endpoint edge case */ const modelsConfig = queryClient.getQueryData([QueryKeys.models]); - const endpointsConfig = queryClient.getQueryData([QueryKeys.endpoints]); const defaultEndpoint = getDefaultEndpoint({ convoSetup: conversation, endpointsConfig, @@ -51,10 +51,10 @@ const useNavigateToConvo = (index = 0) => { const models = modelsConfig?.[defaultEndpoint ?? ''] ?? []; convo = buildDefaultConvo({ + models, conversation, endpoint: defaultEndpoint, lastConversationSetup: conversation, - models, }); } clearAllConversations(true); @@ -68,7 +68,7 @@ const useNavigateToConvo = (index = 0) => { invalidateMessages?: boolean, ) => { if (!conversation) { - console.log('Conversation not provided'); + logger.warn('conversation', 'Conversation not provided to `navigateToConvo`'); return; } // set conversation to the new conversation @@ -78,7 +78,7 @@ const useNavigateToConvo = (index = 0) => { lastSelectedTools = JSON.parse(localStorage.getItem(LocalStorageKeys.LAST_TOOLS) ?? '') ?? []; } catch (e) { - // console.error(e); + logger.error('conversation', 'Error parsing last selected tools', e); } const hasTools = (conversation.tools?.length ?? 0) > 0; navigateToConvo( diff --git a/client/src/utils/buildDefaultConvo.ts b/client/src/utils/buildDefaultConvo.ts index 429e400cf..7d60aecfd 100644 --- a/client/src/utils/buildDefaultConvo.ts +++ b/client/src/utils/buildDefaultConvo.ts @@ -8,14 +8,14 @@ import type { TConversation } from 'librechat-data-provider'; import { getLocalStorageItems } from './localStorage'; const buildDefaultConvo = ({ + models, conversation, endpoint = null, - models, lastConversationSetup, }: { - conversation: TConversation; - endpoint: EModelEndpoint | null; models: string[]; + conversation: TConversation; + endpoint?: EModelEndpoint | null; lastConversationSetup: TConversation | null; }): TConversation => { const { lastSelectedModel, lastSelectedTools } = getLocalStorageItems(); @@ -33,7 +33,7 @@ const buildDefaultConvo = ({ const model = lastConversationSetup?.model ?? lastSelectedModel?.[endpoint] ?? ''; const secondaryModel: string | null = endpoint === EModelEndpoint.gptPlugins - ? lastConversationSetup?.agentOptions?.model ?? lastSelectedModel?.secondaryModel ?? null + ? (lastConversationSetup?.agentOptions?.model ?? lastSelectedModel?.secondaryModel ?? null) : null; let possibleModels: string[], secondaryModels: string[]; diff --git a/client/src/utils/logger.ts b/client/src/utils/logger.ts index 413a96f17..6bc1d21db 100644 --- a/client/src/utils/logger.ts +++ b/client/src/utils/logger.ts @@ -4,12 +4,17 @@ const loggerFilter = import.meta.env.VITE_LOGGER_FILTER || ''; type LogFunction = (...args: unknown[]) => void; -const createLogFunction = (consoleMethod: LogFunction): LogFunction => { +const createLogFunction = ( + consoleMethod: LogFunction, + type?: 'log' | 'warn' | 'error' | 'info' | 'debug' | 'dir', +): LogFunction => { return (...args: unknown[]) => { if (isDevelopment || isLoggerEnabled) { const tag = typeof args[0] === 'string' ? args[0] : ''; if (shouldLog(tag)) { - if (tag && args.length > 1) { + if (tag && typeof args[1] === 'string' && type === 'error') { + consoleMethod(`[${tag}] ${args[1]}`, ...args.slice(2)); + } else if (tag && args.length > 1) { consoleMethod(`[${tag}]`, ...args.slice(1)); } else { consoleMethod(...args); @@ -20,12 +25,12 @@ const createLogFunction = (consoleMethod: LogFunction): LogFunction => { }; const logger = { - log: createLogFunction(console.log), - warn: createLogFunction(console.warn), - error: createLogFunction(console.error), - info: createLogFunction(console.info), - debug: createLogFunction(console.debug), - dir: createLogFunction(console.dir), + log: createLogFunction(console.log, 'log'), + dir: createLogFunction(console.dir, 'dir'), + warn: createLogFunction(console.warn, 'warn'), + info: createLogFunction(console.info, 'info'), + error: createLogFunction(console.error, 'error'), + debug: createLogFunction(console.debug, 'debug'), }; function shouldLog(tag: string): boolean {