unicloud.addinterceptor 必须在 main.js 中注册,因为它是应用最早执行的入口,确保拦截器在所有云函数调用前生效;若延迟注册则无法捕获已发出的请求。

uniCloud.addInterceptor 为什么必须在 main.js 里注册
因为拦截器只对后续调用生效,uniCloud.addInterceptor 必须在任何 uniCloud.callFunction 执行前完成注册,否则函数调用已发出、响应已返回,拦截器根本收不到。main.js 是整个应用最早执行的 JS 入口,这里注册才能覆盖全部云函数调用。
常见错误现象:callFunction 返回了 { result: { errCode: 401, errMsg: "token expired" } },但页面里没做任何处理,直接取 result.data 导致报错或白屏。
- 不能写在某个页面的
onLoad或methods里 —— 此时已有云函数调用完成,拦截器形同虚设 - 不能依赖条件判断后才注册 —— 比如“只有登录态才注册”,会导致未登录时的首次调用(如获取公共配置)无法被拦截
- 注册位置错误的典型表现:开发时偶尔能捕获错误,上线后大量
undefined或Cannot read property 'xxx' of undefined报错
success 回调里 throw new Error 会中断业务逻辑吗
不会中断,但会把错误抛给上层 Promise 链 —— 这正是你想要的效果。拦截器里的 throw new Error 不会让页面卡死,而是让 uniCloud.callFunction 的 .catch() 或 try/catch 捕获到,你可以统一跳转登录页、弹 toast 或静默重试。
示例场景:多个页面都调用了 getUserInfo 云函数,Token 过期后返回 errCode: 401:
uniCloud.addInterceptor('callFunction', {
success(res) {
const { result } = res
if (result?.errCode === 401) {
uni.removeStorageSync('token')
uni.navigateTo({ url: '/pages/login/login' })
throw new Error('login_required') // 让当前调用立即失败,避免后续代码执行
}
}
})
- 不 throw,只是
uni.navigateTo,那当前函数的then还会继续执行,可能造成数据渲染错乱 - throw 后,当前
callFunction的 Promise 立即 reject,上层可统一 catch 处理 - 注意:
throw只影响当前这次调用,不影响其他并行请求
fail 回调要处理哪些真实网络错误
fail 拦截的是底层网络异常,比如断网、超时、服务不可达、CORS 被拒(尤其 H5 端未开启「本地云函数」)、云函数名不存在等。这些错误不会进入 success,所以必须单独处理。
常见错误信息包括:"request:fail net::ERR_CONNECTION_REFUSED"、"request:fail timeout"、"function not found"、"Network Error"。
- H5 端调试时出现
net::ERR_CONNECTION_REFUSED,90% 是没勾选 manifest.json 里的「H5 使用本地云函数」 - 小程序真机报
function not found,大概率是云函数文件夹名和name参数大小写不一致,或没右键上传部署 - 不能只靠
success拦截业务错误码(如 401/500),fail必须兜底网络层问题,否则用户断网时页面直接白屏无提示
如何区分业务错误和系统错误并分级上报
真正的工程化错误处理不是统一弹窗,而是按错误类型分流:401 跳登录、404 提示资源不存在、500 上报监控、网络错误提示“请检查网络”,而 addInterceptor 是唯一能全局介入所有云函数响应的地方。
关键点在于从 res 或 err 中提取结构化字段,避免字符串匹配:
uniCloud.addInterceptor('callFunction', {
success(res) {
const { result } = res
if (result?.errCode) {
// 业务错误:走业务码分支
reportBizError(result.errCode, result.errMsg)
}
},
fail(err) {
// 系统错误:走网络/环境分支
reportSysError(err.errMsg || err.message)
}
})
- 不要在拦截器里直接
uni.showToast—— 提示策略应由业务决定(有些后台接口失败不该打扰用户) - 上报函数
reportBizError应携带上下文:当前页面路径、用户 ID(脱敏)、时间戳、云函数名 - 正式包务必关闭
debug: true,否则日志可能泄露敏感信息或拖慢性能
try/catch、或在页面里重复处理 errCode,都会导致逻辑割裂和维护黑洞。











