Skip to content

Commit 33a5206

Browse files
authored
bug-fix: Add fallback logic on template rendering error (#1017)
Fixes: [<TICKET_ID>](https://sendbird.atlassian.net/browse/<TICKET_ID>) <img width="460" alt="Screenshot 2024-03-15 at 4 06 48 PM" src="https://github.com/sendbird/sendbird-uikit-react/assets/16806397/b59d4560-2a2f-4ca4-a257-2af18d9e889f"> <img width="478" alt="Screenshot 2024-03-15 at 4 06 34 PM" src="https://github.com/sendbird/sendbird-uikit-react/assets/16806397/63b3dc59-e333-4e2a-b93e-480ae1564d71"> ### Changelogs -
1 parent 4527ab7 commit 33a5206

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Component, ErrorInfo, ReactNode } from 'react';
2+
import { LoggerInterface } from '../../lib/Logger';
3+
4+
interface ErrorBoundaryProps {
5+
children: ReactNode;
6+
fallbackMessage: ReactNode;
7+
logger?: LoggerInterface;
8+
}
9+
10+
interface ErrorBoundaryState {
11+
hasError: boolean;
12+
}
13+
14+
export class MessageTemplateErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
15+
constructor(props: ErrorBoundaryProps) {
16+
super(props);
17+
this.state = { hasError: false };
18+
}
19+
20+
static getDerivedStateFromError() {
21+
return { hasError: true };
22+
}
23+
24+
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
25+
this.props.logger?.error('Error caught by ErrorBoundary:', error, errorInfo);
26+
}
27+
28+
render() {
29+
if (this.state.hasError) {
30+
return this.props.fallbackMessage;
31+
}
32+
return this.props.children;
33+
}
34+
}
35+
36+
export default MessageTemplateErrorBoundary;

src/ui/TemplateMessageItemBody/index.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import useSendbirdStateContext from '../../hooks/useSendbirdStateContext';
1212
import { ProcessedMessageTemplate, WaitingTemplateKeyData } from '../../lib/dux/appInfo/initialState';
1313
import FallbackTemplateMessageItemBody from './FallbackTemplateMessageItemBody';
1414
import LoadingTemplateMessageItemBody from './LoadingTemplateMessageItemBody';
15+
import MessageTemplateErrorBoundary from '../MessageTemplate/messageTemplateErrorBoundary';
1516

1617
const TEMPLATE_FETCH_RETRY_BUFFER_TIME_IN_MILLIES = 500; // It takes about 450ms for isError update
1718

@@ -48,6 +49,9 @@ export function TemplateMessageItemBody({
4849
isByMe = false,
4950
theme = 'light',
5051
}: TemplateMessageItemBodyProps): ReactElement {
52+
const store = useSendbirdStateContext();
53+
const logger = store?.config?.logger;
54+
5155
const templateData: MessageTemplateData | undefined = message.extendedMessagePayload?.['template'] as MessageTemplateData;
5256
if (!templateData?.key) {
5357
return <FallbackTemplateMessageItemBody className={className} message={message} isByMe={isByMe} />;
@@ -139,7 +143,12 @@ export function TemplateMessageItemBody({
139143
isByMe ? 'outgoing' : 'incoming',
140144
'sendbird-template-message-item-body',
141145
])}>
142-
<MessageTemplateWrapper message={message} templateItems={filledMessageTemplateItems} />
146+
<MessageTemplateErrorBoundary
147+
fallbackMessage={<FallbackTemplateMessageItemBody className={className} message={message} isByMe={isByMe}/>}
148+
logger={logger}
149+
>
150+
<MessageTemplateWrapper message={message} templateItems={filledMessageTemplateItems}/>
151+
</MessageTemplateErrorBoundary>
143152
</div>
144153
);
145154
}

0 commit comments

Comments
 (0)