Skip to content

Commit

Permalink
fix(chat): add error boundary for invalid form schema (Issue #2901) (#…
Browse files Browse the repository at this point in the history
…2904)

Co-authored-by: Magomed-Elbi Dzhukalaev <[email protected]>
  • Loading branch information
Gimir and Magomed-Elbi Dzhukalaev authored Jan 7, 2025
1 parent 2b64409 commit 3b748fd
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 3 deletions.
2 changes: 2 additions & 0 deletions apps/chat/src/components/Chat/ChatMessage/ChatMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export const ChatMessage: FC<Props> = memo(
}}
toggleEditing={toggleEditing}
isEditing={isEditing}
editDisabled={editDisabled}
toggleEditingTemplates={toggleEditingTemplates}
isEditingTemplates={isTemplateModalOpened}
messageCopied={messageCopied}
Expand Down Expand Up @@ -152,6 +153,7 @@ export const ChatMessage: FC<Props> = memo(
isLastMessage={isLastMessage}
messageIndex={messageIndex}
conversation={conversation}
editDisabled={editDisabled}
isEditing={isEditing}
toggleEditing={toggleEditing}
toggleEditingTemplates={toggleEditingTemplates}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useAppSelector } from '@/src/store/hooks';
import { SettingsSelectors } from '@/src/store/settings/settings.reducers';

import { MessageAssistantButtons } from '@/src/components/Chat/ChatMessage/MessageButtons';
import { AssistantSchema } from '@/src/components/Chat/ChatMessage/MessageSchema/AssistantSchema';
import { AssistantSchema } from '@/src/components/Chat/ChatMessage/MessageSchema/MessageSchema';
import { MessageAttachments } from '@/src/components/Chat/MessageAttachments';
import { MessageStages } from '@/src/components/Chat/MessageStages';
import { ErrorMessage } from '@/src/components/Common/ErrorMessage';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { FOLDER_ATTACHMENT_CONTENT_TYPE } from '@/src/constants/folders';
import { ChatInputAttachments } from '@/src/components/Chat/ChatInput/ChatInputAttachments';
import { AdjustedTextarea } from '@/src/components/Chat/ChatMessage/AdjustedTextarea';
import { MessageUserButtons } from '@/src/components/Chat/ChatMessage/MessageButtons';
import { UserSchema } from '@/src/components/Chat/ChatMessage/MessageSchema/UserSchema';
import { UserSchema } from '@/src/components/Chat/ChatMessage/MessageSchema/MessageSchema';
import { MessageAttachments } from '@/src/components/Chat/MessageAttachments';
import { AttachButton } from '@/src/components/Files/AttachButton';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useTranslation } from 'next-i18next';

import { Translation } from '@/src/types/translation';

import { withErrorBoundary } from '@/src/components/Common/ErrorBoundary';
import { ErrorMessage } from '@/src/components/Common/ErrorMessage';

import { AssistantSchema as MemoAssistantSchema } from './AssistantSchema';
import { UserSchema as MemoUserSchema } from './UserSchema';

const InvalidSchemaMessage = () => {
const { t } = useTranslation(Translation.Chat);

return (
<div className="mt-2">
<ErrorMessage error={t('Form schema is invalid') ?? ''} />
</div>
);
};

const config = {
errorLogMessage: 'Invalid schema error:',
};

export const UserSchema = withErrorBoundary(
MemoUserSchema,
<InvalidSchemaMessage />,
config,
);

export const AssistantSchema = withErrorBoundary(
MemoAssistantSchema,
<InvalidSchemaMessage />,
config,
);
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ export const UserSchema = memo(function UserSchema({

if (isEditing)
return (
<FormSchema schema={schema} onChange={handleChange} disabled={disabled} />
<FormSchema
schema={schema}
onChange={handleChange}
formValue={formValue}
showSelected
disabled={disabled}
/>
);

return userForm.length ? (
Expand Down
56 changes: 56 additions & 0 deletions apps/chat/src/components/Common/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Component, ComponentType, ReactNode } from 'react';

interface ErrorBoundaryProps {
children: ReactNode;
fallback?: ReactNode;
config?: {
errorLogMessage?: string;
};
}

interface ErrorBoundaryState {
hasError: boolean;
}

export class ErrorBoundary extends Component<
ErrorBoundaryProps,
ErrorBoundaryState
> {
constructor(props: ErrorBoundaryProps) {
super(props);
this.state = { hasError: false };
}

static getDerivedStateFromError(): ErrorBoundaryState {
return { hasError: true };
}

componentDidCatch(error: Error) {
if (this.props.config?.errorLogMessage) {
console.error(this.props.config.errorLogMessage, ': ', error);
}
}

render() {
if (this.state.hasError) {
return this.props.fallback ?? this.props.children;
}
return this.props.children;
}
}

export function withErrorBoundary<T extends object>(
Component: ComponentType<T>,
fallback?: ReactNode,
config?: ErrorBoundaryProps['config'],
) {
const ErrorBoundaryWrapper = (props: T) => (
<ErrorBoundary fallback={fallback} config={config}>
<Component {...props} />
</ErrorBoundary>
);

ErrorBoundaryWrapper.displayName = 'ErrorBoundaryWrapper';

return ErrorBoundaryWrapper;
}

0 comments on commit 3b748fd

Please sign in to comment.