You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

5.7 KiB

前端错误处理工具函数

日期: 2026-01-27
类型: 功能增强
影响范围: 错误处理、用户体验

变更概述

创建统一的错误处理工具函数,简化前端错误处理逻辑,适配后端统一响应格式。

问题背景

前端代码中错误处理不统一:

// 各种不同的错误处理方式
error.response?.data?.detail
error.response?.data?.message
error.message

这导致:

  1. 代码重复
  2. 容易遗漏错误消息
  3. 难以适配新的响应格式

解决方案

创建错误处理工具函数

文件: client/src/lib/error-utils.ts

1. 提取错误消息

export function getErrorMessage(
  error: unknown, 
  fallback = '操作失败,请稍后重试'
): string

使用示例

try {
  await apiClient.post('/auth/login/phone', data);
} catch (error) {
  toast({
    variant: 'destructive',
    title: '登录失败',
    description: getErrorMessage(error, '请检查手机号和验证码'),
  });
}

2. 获取错误状态码

export function getErrorCode(error: unknown): number | undefined

使用示例:

const code = getErrorCode(error);
if (code === 401) {
  // 跳转登录
}

3. 获取错误详情

export function getErrorData(error: unknown): any

使用示例

const data = getErrorData(error);
if (data?.errors) {
  // 显示验证错误详情
}

4. 错误类型判断

export function isAuthError(error: unknown): boolean        // 401/403
export function isValidationError(error: unknown): boolean  // 422
export function isRateLimitError(error: unknown): boolean   // 429

使用示例

if (isValidationError(error)) {
  const errors = formatValidationErrors(error);
  // 显示字段级错误
}

5. 格式化验证错误

export function formatValidationErrors(error: unknown): string[]

使用示例

const errors = formatValidationErrors(error);
// ["body -> code: Field required", "body -> phone: Invalid format"]

适配统一响应格式

工具函数自动适配新旧两种格式:

新格式(RFC-135)

{
  success: false,
  code: 400,
  message: "验证码错误",
  data: null,
  timestamp: "2026-01-27T08:00:00Z"
}

// 响应拦截器转换后
error.message = "验证码错误"
error.code = 400
error.data = null

旧格式(兼容)

{
  detail: "验证码错误"
}

// 工具函数兼容处理
getErrorMessage(error) // → "验证码错误"

使用指南

基础用法

import { getErrorMessage } from '@/lib/error-utils';

try {
  await someApiCall();
} catch (error) {
  // 简单场景:只显示错误消息
  toast({
    variant: 'destructive',
    description: getErrorMessage(error),
  });
}

高级用法

import { 
  getErrorMessage, 
  getErrorCode,
  isValidationError,
  formatValidationErrors 
} from '@/lib/error-utils';

try {
  await someApiCall();
} catch (error) {
  const code = getErrorCode(error);
  
  // 参数验证错误:显示详细字段错误
  if (isValidationError(error)) {
    const errors = formatValidationErrors(error);
    errors.forEach(err => {
      toast({ description: err });
    });
    return;
  }
  
  // 其他错误:显示通用消息
  toast({
    variant: 'destructive',
    title: `错误 ${code}`,
    description: getErrorMessage(error),
  });
}

React Hook Form 集成

import { getErrorMessage } from '@/lib/error-utils';

const onSubmit = async (data: FormData) => {
  try {
    await apiClient.post('/api/endpoint', data);
  } catch (error) {
    // 设置表单错误
    form.setError('root', {
      message: getErrorMessage(error),
    });
  }
};

已更新文件

  • client/src/pages/LoginPage.tsx - 登录页面错误处理

待更新文件

以下文件仍使用旧的错误处理方式,建议逐步迁移:

  • client/src/components/common/EditProfileModal.tsx
  • client/src/components/features/project/CreateProjectModal.tsx
  • client/src/components/features/project/CreateFolderModal.tsx
  • client/src/components/features/project/DeleteConfirmModal.tsx
  • client/src/components/features/project/CloneFolderModal.tsx
  • client/src/components/features/project/MoveFolderModal.tsx
  • client/src/components/features/project/ProjectContextMenu.tsx
  • client/src/components/common/UserPopover.tsx

迁移指南

替换模式

旧代码

catch (error: any) {
  toast({
    description: error.response?.data?.detail || '操作失败',
  });
}

新代码

import { getErrorMessage } from '@/lib/error-utils';

catch (error) {
  toast({
    description: getErrorMessage(error, '操作失败'),
  });
}

批量替换建议

  1. 导入工具函数:import { getErrorMessage } from '@/lib/error-utils';
  2. 替换错误消息提取:error.response?.data?.detailgetErrorMessage(error)
  3. 移除 any 类型:catch (error: any)catch (error)

优势

  1. 统一性:所有错误处理使用相同的工具函数
  2. 兼容性:自动适配新旧响应格式
  3. 类型安全:TypeScript 类型支持
  4. 可维护性:集中管理错误处理逻辑
  5. 可扩展性:易于添加新的错误处理功能

相关文档

后续优化

  1. 逐步迁移所有组件使用新的错误处理工具
  2. 添加错误追踪和上报功能
  3. 实现错误重试机制
  4. 添加错误边界组件集成