You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 === false
  • data.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 14:42:17