react-query中useQuery的onError回调接收null错误对象的原因及解决方法咨询
这个问题我之前也碰到过,咱们来一步步拆解原因和对应的解决办法:
可能的原因
查询函数返回值与泛型不匹配
你的代码里,useQuery的泛型定义是<Subject, Error>,意味着成功数据必须是Subject类型,但查询函数在subjectId为空字符串时(注意enabled条件是subjectId !== null,空字符串会通过这个判断)返回了null。这种类型不匹配可能导致react-query内部把这个返回值错误地当作异常处理,最终给onError传了null。查询被取消的边界场景
当查询被取消时(比如组件卸载、enabled从true切为false导致查询中止),某些react-query版本可能会意外触发onError并传递null作为错误参数。虽然正常情况下取消查询应该触发onSettled而非onError,但查询正在执行时被取消的场景下可能出现这个问题。重试函数的类型隐患
你给重试函数定义的error参数类型是Error,但实际上react-query传递的错误可能是null或unknown。如果某次重试触发时错误为null,后续onError也可能收到这个null值。
解决方案
针对这些问题,咱们逐个修复:
修正查询函数和泛型定义
首先,如果允许成功数据为null,要更新泛型,同时确保查询函数返回Promise:return useQuery<Subject | null, Error>(['subject', subjectId], () => { if (subjectId) { return serverAccess.subject.viewSubject(subjectId) } else { // 必须返回Promise,不能直接return null return Promise.resolve(null) } }, { // 优化enabled条件,过滤空字符串、null、undefined enabled: !!subjectId, // ...其他配置 })在onError中添加空值校验
不管什么原因,访问err.message前先检查err是否存在,避免报错:onError: (err) => { console.log("Error value", err) if (err) { store.dispatch(addBackgroundError(err.message, guid)) } else { // 可以在这里处理null错误的情况,比如打个警告日志 console.warn("onError received null error") } }修正重试函数的参数类型
把重试函数的error参数改为Error | null,并用可选链避免报错:retry: (failureCount: number, error: Error | null) => { if (error?.message === "Subject does not exist") { return false; } if (failureCount >= 3) { return false; } return true; },
这样应该就能彻底解决你遇到的Cannot read property message of null问题了。
内容的提问来源于stack exchange,提问作者shaked

