fix: 修复聊天记录页面崩溃问题并添加错误边界保护

This commit is contained in:
hicccc77
2026-03-08 18:51:20 +08:00
parent e54eb8fea2
commit 836032d93e
3 changed files with 67 additions and 14 deletions

View File

@@ -0,0 +1,41 @@
import { Component, ReactNode } from 'react'
interface Props {
children: ReactNode
fallback?: ReactNode
}
interface State {
hasError: boolean
error?: Error
}
export class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props)
this.state = { hasError: false }
}
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error }
}
componentDidCatch(error: Error, errorInfo: any) {
console.error('ErrorBoundary caught:', error, errorInfo)
}
render() {
if (this.state.hasError) {
return this.props.fallback || (
<div style={{ padding: '20px', textAlign: 'center', color: '#999' }}>
<p></p>
<p style={{ fontSize: '12px', marginTop: '8px' }}>
{this.state.error?.message || '未知错误'}
</p>
</div>
)
}
return this.props.children
}
}

View File

@@ -33,6 +33,16 @@
gap: 12px;
align-items: flex-start;
&.error-item {
padding: 12px;
background: var(--bg-secondary);
border-radius: 8px;
color: var(--text-tertiary);
font-size: 13px;
text-align: center;
justify-content: center;
}
.avatar {
width: 40px;
height: 40px;

View File

@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'
import { useParams, useLocation } from 'react-router-dom'
import { ChatRecordItem } from '../types/models'
import TitleBar from '../components/TitleBar'
import { ErrorBoundary } from '../components/ErrorBoundary'
import './ChatHistoryPage.scss'
export default function ChatHistoryPage() {
@@ -166,7 +167,9 @@ export default function ChatHistoryPage() {
<div className="status-msg empty"></div>
) : (
recordList.map((item, i) => (
<HistoryItem key={i} item={item} />
<ErrorBoundary key={i} fallback={<div className="history-item error-item"></div>}>
<HistoryItem item={item} />
</ErrorBoundary>
))
)}
</div>
@@ -175,6 +178,8 @@ export default function ChatHistoryPage() {
}
function HistoryItem({ item }: { item: ChatRecordItem }) {
const [imageError, setImageError] = useState(false)
// sourcetime 在合并转发里有两种格式:
// 1) 时间戳(秒) 2) 已格式化的字符串 "2026-01-21 09:56:46"
let time = ''
@@ -197,19 +202,16 @@ function HistoryItem({ item }: { item: ChatRecordItem }) {
if (src) {
return (
<div className="media-content">
{imageError ? (
<div className="media-tip"></div>
) : (
<img
src={src}
alt="图片"
referrerPolicy="no-referrer"
onError={(e) => {
const target = e.target as HTMLImageElement
target.style.display = 'none'
const placeholder = document.createElement('div')
placeholder.className = 'media-tip'
placeholder.textContent = '图片无法加载'
target.parentElement?.appendChild(placeholder)
}}
onError={() => setImageError(true)}
/>
)}
</div>
)
}