RTK Query useQuery超时错误未触发transformErrorResponse求助
问题
我在RTK Query的查询端点中配置了transformErrorResponse以返回自定义错误对象,代码如下:
export const myAPI = createApi({ reducerPath: 'myAPI', baseQuery: fetchBaseQuery({ baseUrl: 'https://my.site.com/api/', }), endpoints: (builder) => ({ getUserInfo: builder.query<string, string>({ query: (params) => ({ url: 'user/' + params, method: 'GET', timeout: 1, // <-- 故意设置短超时以测试错误场景 }), transformErrorResponse: async (baseQueryReturnValue) => { const err = { message: 'some custom error msg', code: 'custom code string here', }; return err; }, }), }), }); export const { useGetUserInfoQuery } = myAPI;
该配置在多数场景下正常工作,但当查询因超时(TIMEOUT_ERROR)被中止时,始终返回默认错误:
{"message": "Aborted", "name": "AbortError"}
似乎transformErrorResponse代码并未执行。我通过以下方式使用useQuery钩子获取错误:
const { isLoading, isFetching, error, data } = useGetUserInfoQuery('userNameHere');
请问是否存在其他方式可自定义查询因超时中止时返回的错误?
解决方案
问题核心在于fetchBaseQuery的超时逻辑:超时触发的AbortError属于请求层面的中止,不会进入transformErrorResponse处理流程——这个钩子仅负责处理服务器返回的错误响应(如4xx/5xx状态码),而超时中止属于请求未完成的异常情况。
你可以通过以下两种方式自定义超时错误:
1. 封装自定义baseQuery,全局拦截AbortError
在fetchBaseQuery外层包装逻辑,捕获超时导致的AbortError并转换为自定义错误,所有使用该baseQuery的端点都会自动生效:
const customBaseQuery = async (args, api, extraOptions) => { try { return await fetchBaseQuery({ baseUrl: 'https://my.site.com/api/', })(args, api, extraOptions); } catch (error) { // 判断是否为超时/中止错误 if (error.name === 'AbortError') { return { error: { message: '请求超时,请稍后重试', code: 'TIMEOUT_CUSTOM', }, }; } // 其他错误原样抛出,交由transformErrorResponse处理 throw error; } }; // 在createApi中使用自定义baseQuery export const myAPI = createApi({ reducerPath: 'myAPI', baseQuery: customBaseQuery, endpoints: (builder) => ({ getUserInfo: builder.query<string, string>({ query: (params) => ({ url: 'user/' + params, method: 'GET', timeout: 1, }), // 保留原有逻辑处理服务器返回的错误 transformErrorResponse: (baseQueryReturnValue) => { return { message: 'some custom error msg', code: 'custom code string here', }; }, }), }), });
2. 组件内直接判断错误类型,局部转换
如果仅需单个组件处理超时错误,可在使用钩子时直接判断错误对象类型:
const { isLoading, isFetching, error, data } = useGetUserInfoQuery('userNameHere'); // 生成自定义错误对象 const customError = error ? error.name === 'AbortError' ? { message: '请求超时,请稍后重试', code: 'TIMEOUT_CUSTOM' } : error : null;
内容的提问来源于stack exchange,提问作者aaronfg
相关产品推荐
相关产品推荐

