# Toast 错误对象渲染问题修复 ## 问题描述 在保存标注结果时出现错误: ``` Objects are not valid as a React child (found: object with keys {type, loc, msg, input, url}) ``` ## 问题原因 FastAPI 的验证错误返回的是一个对象数组,每个对象包含: - `type`: 错误类型 - `loc`: 错误位置(字段路径) - `msg`: 错误消息 - `input`: 输入值 - `url`: 文档链接 当这个对象直接传递给 Toast 组件时,React 无法渲染对象,导致错误。 ## 解决方案 ### 1. 增强 API 拦截器错误处理 在 `web/apps/lq_label/src/services/api.ts` 中: ```typescript apiClient.interceptors.response.use( (response) => response, (error: AxiosError) => { let errorMessage = '发生了意外错误'; if (error.response?.data) { const data = error.response.data as any; // Handle FastAPI validation errors (array of error objects) if (Array.isArray(data.detail)) { // Format validation errors into readable message errorMessage = data.detail .map((err: any) => { const field = err.loc?.join('.') || '字段'; return `${field}: ${err.msg}`; }) .join('; '); } // Handle simple string error message else if (typeof data.detail === 'string') { errorMessage = data.detail; } // Handle object error message else if (typeof data.detail === 'object' && data.detail !== null) { errorMessage = JSON.stringify(data.detail); } // Fallback to error message else if (data.message) { errorMessage = data.message; } } else if (error.message) { errorMessage = error.message; } toast.error(errorMessage); // ... } ); ``` **改进点**: - ✅ 检测 FastAPI 验证错误数组 - ✅ 格式化为可读的字符串(`字段: 错误消息`) - ✅ 处理多种错误格式(字符串、对象、数组) - ✅ 提供详细的调试日志 ### 2. 增强 Toast 服务的类型安全 在 `web/apps/lq_label/src/services/toast.ts` 中: ```typescript error(message: string | any, title?: string, duration = 5000): void { // 确保 message 是字符串 let messageStr: string; if (typeof message === 'string') { messageStr = message; } else if (message && typeof message === 'object') { // 如果是对象,尝试提取有用信息 if (message.message) { messageStr = message.message; } else if (message.msg) { messageStr = message.msg; } else { messageStr = JSON.stringify(message); } } else { messageStr = String(message); } this.notify({ type: ToastType.error, title: title || '错误', message: messageStr, duration, }); } ``` **改进点**: - ✅ 接受任意类型的 message 参数 - ✅ 自动转换对象为字符串 - ✅ 尝试提取对象中的 `message` 或 `msg` 字段 - ✅ 最后兜底使用 `JSON.stringify()` 或 `String()` ## 错误格式示例 ### FastAPI 验证错误格式 ```json { "detail": [ { "type": "string_type", "loc": ["body", "name"], "msg": "Input should be a valid string", "input": null, "url": "https://errors.pydantic.dev/..." }, { "type": "missing", "loc": ["body", "data"], "msg": "Field required", "input": {"name": "test"}, "url": "https://errors.pydantic.dev/..." } ] } ``` ### 格式化后的错误消息 ``` body.name: Input should be a valid string; body.data: Field required ``` ## 测试场景 修复后,以下场景都能正确显示错误消息: 1. ✅ FastAPI 验证错误(对象数组) 2. ✅ 简单字符串错误 3. ✅ 对象错误 4. ✅ 网络错误 5. ✅ 超时错误 ## 相关文件 - `web/apps/lq_label/src/services/api.ts` - API 拦截器 - `web/apps/lq_label/src/services/toast.ts` - Toast 服务 ## 验证方法 1. 尝试提交空的表单字段 2. 尝试提交无效的 JSON 数据 3. 尝试在网络断开时保存数据 4. 检查 Toast 是否显示可读的错误消息 ## 总结 通过增强错误处理逻辑,现在系统能够: - ✅ 正确处理 FastAPI 的验证错误 - ✅ 将错误对象转换为可读的字符串 - ✅ 在 Toast 中显示友好的错误消息 - ✅ 避免 React 渲染对象的错误