Loading...
Loading...
Compare original and translation side by side
| Error Type | Example | Typical Response |
|---|---|---|
| Validation | Invalid form input | Inline correction guidance |
| Network | Timeout, offline, DNS failure | Retry, offline fallback, preserve user intent |
| Authorization | 401, 403 | Re-auth, permission message, redirect |
| Server | 500, dependency outage | Retry or graceful fallback |
| Not found | Missing route or deleted record | Not-found UI, navigation recovery |
| Conflict | Stale write, version mismatch | Refresh, merge, or ask user to resolve |
| Rendering | Component crash | Error boundary, fallback UI |
| Background failure | Polling or refresh failure | Non-blocking notification, degraded data state |
| 错误类型 | 示例 | 典型响应 |
|---|---|---|
| 验证错误 | 无效表单输入 | 内联修正指引 |
| 网络错误 | 超时、离线、DNS失败 | 重试、离线回退、保留用户操作意图 |
| 授权错误 | 401、403 | 重新授权、权限提示、重定向 |
| 服务器错误 | 500、依赖服务中断 | 重试或优雅回退 |
| 未找到错误 | 路由缺失或记录已删除 | 未找到UI、导航恢复 |
| 冲突错误 | 过时写入、版本不匹配 | 刷新、合并或请求用户解决 |
| 渲染错误 | 组件崩溃 | Error Boundaries、回退UI |
| 后台故障 | 轮询或刷新失败 | 非阻塞通知、降级数据状态 |
{
code: 'NETWORK_TIMEOUT',
message: 'Request timed out',
retryable: true,
statusCode: 504,
requestId: 'req_123'
}{
code: 'NETWORK_TIMEOUT',
message: 'Request timed out',
retryable: true,
statusCode: 504,
requestId: 'req_123'
}Unknown exception occurredWe couldn’t save your changes. Check your connection and try again.Unknown exception occurred我们无法保存您的更改。请检查网络连接后重试。| UI Placement | Best For |
|---|---|
| Inline near field | Validation and input-specific errors |
| Inline near component | Failed widget or card action |
| Page-level message | Page data load failure |
| Toast | Secondary status updates, non-blocking failures |
| Full-screen fallback | Fatal route or app crash |
| UI位置 | 适用场景 |
|---|---|
| 字段附近内联 | 验证和特定输入错误 |
| 组件附近内联 | 部件或卡片操作失败 |
| 页面级消息 | 页面数据加载失败 |
| 提示弹窗(Toast) | 次要状态更新、非阻塞故障 |
| 全屏回退 | 致命路由或应用崩溃 |
for (let attempt = 0; attempt < 3; attempt++) {
try {
return await request();
} catch (error) {
if (!isRetryable(error)) throw error;
await wait(2 ** attempt * 500);
}
}for (let attempt = 0; attempt < 3; attempt++) {
try {
return await request();
} catch (error) {
if (!isRetryable(error)) throw error;
await wait(2 ** attempt * 500);
}
}<ErrorBoundary fallback={<WidgetError />}>
<RevenueChart />
</ErrorBoundary><ErrorBoundary fallback={<WidgetError />}>
<RevenueChart />
</ErrorBoundary>try {
await saveProfile(input);
setStatus('saved');
} catch (error) {
setStatus('error');
setErrorMessage(toUserMessage(error));
}try {
await saveProfile(input);
setStatus('saved');
} catch (error) {
setStatus('error');
setErrorMessage(toUserMessage(error));
}401403401403| Anti-Pattern | Why It Hurts |
|---|---|
| Generic “Something went wrong” everywhere | Gives no recovery path |
| Swallowing errors silently | Fails without user or developer visibility |
| Retrying non-retryable failures | Wastes time and increases confusion |
| Clearing user input on failed submit | Loses work |
| Treating empty state as error | Produces wrong UX |
| Full-page crash for one failed widget | Over-scopes the failure |
| 反模式 | 危害 |
|---|---|
| 所有地方都用通用的“出了点问题” | 没有提供恢复路径 |
| 静默吞噬错误 | 用户和开发者都无法感知故障 |
| 重试不可重试的故障 | 浪费时间并增加混乱 |
| 提交失败时清除用户输入 | 丢失工作内容 |
| 将空状态视为错误 | 产生错误的UX |
| 单个故障部件导致全页崩溃 | 过度扩大故障范围 |
observability-patternsaccessibility-interaction-patternsoptimistic-ui-patternsdata-fetching-patternsobservability-patternsaccessibility-interaction-patternsoptimistic-ui-patternsdata-fetching-patterns