Pinia Action 异步错误处理应由 Action 显式 throw 错误并附加业务字段,组件通过 await + try/catch 按需响应,辅以 $onAction 兜底和 loading/error 状态可视化反馈。

在组件中捕获 Pinia Action 的异步错误,关键不是“在组件里 try/catch 每个调用”,而是让 Action 本身抛出可识别的错误,并在组件层以统一、可控的方式响应——既不丢失上下文,也不重复写错误处理逻辑。
Action 内部必须主动抛出完整错误
Action 是错误源头,它决定了组件能拿到什么。如果 Action 里只做 this.error = '加载失败' 却不 throw,组件就无法 await 后捕获,也无法区分是网络超时还是业务校验失败。
- 所有 async Action 都应在 catch 块中 显式 throw error,而不是静默吞掉或仅存 message
- 保留原始 error 对象:包括
error.response?.status、error.config?.url、error.stack - 可附加业务字段,比如
error.action = 'submitOrder'、error.orderId = 123,方便组件判断如何响应
组件调用时用 await + try/catch 处理具体场景
当组件需要差异化反馈(如弹窗、跳转、重试按钮),就该在调用处用 try/catch —— 这不是重复劳动,而是职责分离:Action 负责“出错”,组件负责“怎么应对”。
- 按钮点击触发 Action 时,直接 await 并捕获:
try { await store.submitForm() } catch (e) { showErrorToast(e.message) } - 避免在 setup 中无条件 await(会阻塞渲染),只在用户交互或明确需等待结果时使用
- 对非关键操作(如埋点上报),可用
.catch(() => {})忽略,防止未处理 rejection 报 warning
用 $onAction 统一兜底,覆盖遗漏场景
总有组件忘了 try/catch,或错误发生在 Action 内部其他位置(比如嵌套调用另一个 store 的 action)。这时 $onAction 是最后一道防线。
- 在 store 创建后立即注册:
store.$onAction(({ onError }) => { reportErrorToSentry(error) }) - onError 回调能捕获同步 throw 和异步 reject,且自带 action 名称、参数等上下文
- 可结合 error.code 或 status 做分级:401 自动登出,500 显示维护页,网络异常提示重试
配合 loading/error 状态做视觉反馈
光捕获错误不够,用户需要明确感知。Store 内应管理 loading 和 error 字段,组件通过状态而非 Promise 结果来响应。
- 组件 watch store.error,变化时显示提示框;watch store.loading 控制按钮禁用态
- 注意:store.error 应设为 null 或字符串,避免存整个 error 对象导致响应式开销过大
- 若需展示详细错误(如后端返回的 code 字段),可在 Action 中把必要字段解构到 state,例如
this.errorCode = err.response?.data?.code


















