SolidJS createResource请求401时抛出未捕获Promise错误问题
问题根因
createResource存在参数重载歧义:当仅传入一个函数参数时,Solid会在部分场景下将该函数识别为响应式依赖源函数,而非实际执行异步请求的fetcher函数。
响应式源函数的返回值仅作为触发fetcher执行的依赖标记,不会被纳入resource的异步等待、错误捕获流程。你写的axios请求逻辑被识别为源函数后,请求抛出的401 reject错误不会被resource接管,直接成为未捕获的Promise异常;同时resource会一直等待不存在的fetcher返回结果,因此永久停留在loading: true状态,error和值始终为undefined。
解决方案
显式传入两个参数消除重载歧义:第一个参数传入固定值作为无响应式依赖的源(仅初始化时触发一次请求),第二个参数传入实际的异步请求fetcher函数,让Solid的错误处理逻辑正常接管请求状态。
修正后的resource定义代码如下:
export const authUserResource = createResource<AuthUser>( // 固定源,无响应式依赖,仅初始化触发一次请求 undefined, () => axios.get<AuthUser>('/expense-tracker/api/oauth/user').then(res => res.data) );
修正后接口返回401时,resource状态会完全符合预期:
data.loading === falsedata.error为axios抛出的AxiosError实例,可通过data.error.response?.status拿到401状态码data() === undefined- 控制台不会再抛出未捕获Promise错误
业务逻辑适配参考
处理认证状态重定向时,必须等loading状态结束后再判断错误或返回值,避免拿到中间状态:
export const MyComponent = () => { const [data] = authUserResource; createEffect(() => { if (data.loading) return; if (data.error) { // 识别401状态执行重定向 if (data.error.response?.status === 401) { window.location.replace('/login'); } return; } // 已认证场景,拿到用户信息执行后续逻辑 const userInfo = data(); console.log('当前登录用户:', userInfo); }); return ( // 可根据loading状态渲染加载占位 <div> {data.loading ? '用户信息加载中...' : ( /* 页面业务内容 */ )} </div> ) }
如果后续需要在登录/退出后手动刷新用户信息,直接调用resource返回的refetch方法即可:authUserResource[1].refetch()。
内容的提问来源于stack exchange,提问作者craigmiller160
相关产品推荐
相关产品推荐

