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

NextJS 13 App Router中API Routes结合useSWR的错误处理

解决方案

1. 修改API路由(route.js)

在catch块返回带错误状态码的响应,让axios识别为请求错误,避免错误数据流入useSWR的data:

import { NextResponse } from 'next/server'
export async function GET() {
    try {
        console.log("tryapi !", new Date().toLocaleTimeString())
        let data = await fetch('https://dummyjson.com/users')
        // let data = await fetch('https://dummyjson.com/user12d1d') // 模拟错误
        if (!data.ok) {
            // 处理上游API返回的错误状态码
            throw new Error(`上游API错误: ${data.status}`)
        }
        let UserData = await data.json()
        return NextResponse.json({ data: UserData.users })
    } catch (error) {
        // 返回500状态码+错误信息,明确告知客户端请求失败
        return NextResponse.json(
            { message: error.message },
            { status: 500 }
        )
    }
}

2. 调整Fetcher函数

确保axios遇到非200响应时抛出错误,让useSWR能正确捕获error状态:

const Fetcher = url => axios.get(url)
    .then(resp => resp.data.data)
    .catch(err => {
        // 抛出错误,useSWR会将其赋值给error变量
        throw new Error(err.response?.data?.message || '请求失败')
    })

3. 组件逻辑优化(Try.js)

保留原分支判断的同时,给data.map加上可选链,进一步避免渲染报错:

'use client'
import axios from 'axios'
import React from 'react'
import useSWR from 'swr'

const Fetcher = url => axios.get(url)
    .then(resp => resp.data.data)
    .catch(err => {
        throw new Error(err.response?.data?.message || '请求失败')
    })

const Try = () => {
    const { isLoading, error, data, mutate } = useSWR('/api/tryapi', Fetcher)

    if (isLoading) return "Loading...";
    if (error) return (
        <div>
            {error.toString()}
            <br />
            <button onClick={() => mutate()}>Retry</button>
        </div>
    )
    // 仅当data存在时执行map,彻底避免无数据时的报错
    return (
        <div>
            {data?.map((v, i) => (<p key={i}>{v.firstName}</p>))}
        </div>
    )
}

export default Try

方案原理

  • API返回非200状态码时,axios会触发catch分支,fetcher抛出的错误会被useSWR捕获并赋值给error变量,data保持为undefined或缓存值
  • 组件分支判断会优先进入error分支展示错误和重试按钮,不会走到data.map的逻辑
  • mutate()依然能触发重新请求,重试功能完全正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:35:16