mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-21 21:50:49 +02:00
⚙️ refactor: Enhance Logging, Navigation And Error Handling (#5910)
* refactor: Ensure Axios Errors are less Verbose if No Response * refactor: Improve error handling in logAxiosError function * fix: Prevent ModelSelect from rendering for Agent Endpoints * refactor: Enhance logging functions with type parameter for better clarity * refactor: Update buildDefaultConvo function to use optional endpoint parameter since we pass a default value for undefined * refactor: Replace console logs with logger warnings and errors in useNavigateToConvo hook, and handle removed endpoint edge case * chore: import order
This commit is contained in:
parent
93dd365fda
commit
a65647a7de
5 changed files with 57 additions and 56 deletions
|
@ -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}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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({
|
|||
<div className="my-auto lg:max-w-2xl xl:max-w-3xl">
|
||||
<span className="flex w-full flex-col items-center justify-center gap-0 md:order-none md:m-auto md:gap-2">
|
||||
<div className="z-[61] flex w-full items-center justify-center gap-2">
|
||||
{interfaceConfig?.modelSelect === true && (
|
||||
{interfaceConfig?.modelSelect === true && !isAgentsEndpoint(endpoint) && (
|
||||
<ModelSelect
|
||||
conversation={conversation}
|
||||
setOption={setOption}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom';
|
|||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { QueryKeys, EModelEndpoint, LocalStorageKeys, Constants } from 'librechat-data-provider';
|
||||
import type { TConversation, TEndpointsConfig, TModelsConfig } from 'librechat-data-provider';
|
||||
import { buildDefaultConvo, getDefaultEndpoint, getEndpointField } from '~/utils';
|
||||
import { buildDefaultConvo, getDefaultEndpoint, getEndpointField, logger } from '~/utils';
|
||||
import store from '~/store';
|
||||
|
||||
const useNavigateToConvo = (index = 0) => {
|
||||
|
@ -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<TEndpointsConfig>([QueryKeys.endpoints]);
|
||||
if (!convo.endpoint || !endpointsConfig?.[convo.endpoint]) {
|
||||
/* undefined/removed endpoint edge case */
|
||||
const modelsConfig = queryClient.getQueryData<TModelsConfig>([QueryKeys.models]);
|
||||
const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([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(
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue