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

JS Fetch请求失败时的合理返回值方案探讨

优化Fetch请求的错误处理与返回类型

首先先修正你当前代码里的一个bug:第一个.then回调里没有返回res,导致第二个.then拿到的是undefined,根本没法调用res.json(),这会直接引发错误。先把这个问题解决掉:

export async function fetchFoo() {
    const data = await fetch(`http://localhost:9090/foo`, {
        method: "GET",
        redirect: "follow",
    })
        .then((res) => {
            if (!res.ok) {
                throw new Error(res.statusText); // 用new Error更规范
            }
            return res; // 必须返回res,后续才能调用json()
        })
        .then(async (res) => await res.json())
        .catch(() => undefined);

    return data;
}

接下来针对你问的「失败时返回什么类型更合适」,推荐两种实用方案:


方案一:返回带状态标记的统一对象

这种方式能让调用方清晰区分请求成功/失败的状态,同时拿到对应的数据或错误信息,是前端最常用的模式之一。

修改后的函数:

export async function fetchFoo() {
    try {
        const res = await fetch(`http://localhost:9090/foo`, {
            method: "GET",
            redirect: "follow",
        });
        
        if (!res.ok) {
            return {
                success: false,
                error: `请求失败:${res.status} ${res.statusText}`,
                data: null
            };
        }
        
        const data = await res.json();
        return {
            success: true,
            data,
            error: null
        };
    } catch (err) {
        // 处理网络错误(比如断网、跨域等)
        return {
            success: false,
            error: `网络异常:${err.message}`,
            data: null
        };
    }
}

React组件中调用:

function FooComponent() {
    const [result, setResult] = useState(null);

    useEffect(() => {
        const loadData = async () => {
            const res = await fetchFoo();
            if (res.success) {
                // 处理成功数据
                console.log(res.data);
            } else {
                // 展示错误信息
                alert(res.error);
            }
            setResult(res);
        };
        loadData();
    }, []);

    // 渲染逻辑...
}

方案二:让调用方处理错误(不在fetch函数内catch)

如果希望组件能根据不同错误类型做更灵活的处理(比如区分404、500、网络错误),可以不在fetchFoo里捕获错误,而是让函数抛出错误,由调用方用try/catch处理。

修改后的函数:

export async function fetchFoo() {
    const res = await fetch(`http://localhost:9090/foo`, {
        method: "GET",
        redirect: "follow",
    });
    
    if (!res.ok) {
        // 自定义错误对象,携带状态码等信息
        const error = new Error(`请求失败:${res.statusText}`);
        error.statusCode = res.status;
        throw error;
    }
    
    return await res.json();
}

React组件中调用:

function FooComponent() {
    const [data, setData] = useState(null);
    const [error, setError] = useState(null);

    useEffect(() => {
        const loadData = async () => {
            try {
                const resData = await fetchFoo();
                setData(resData);
                setError(null);
            } catch (err) {
                setError(err);
                setData(null);
                // 根据状态码做不同处理
                if (err.statusCode === 404) {
                    alert("资源不存在");
                } else if (err.statusCode >= 500) {
                    alert("服务器内部错误");
                } else {
                    alert(err.message);
                }
            }
        };
        loadData();
    }, []);

    // 渲染逻辑...
}

两种方案各有优劣:方案一适合需要统一处理错误展示的场景,调用方逻辑更简洁;方案二适合需要精细化处理不同错误类型的场景,灵活性更高。你可以根据自己的业务需求选择。

内容的提问来源于stack exchange,提问作者ryno

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 07:48:32