Next.js中如何从服务端向客户端传递并处理自定义错误
在Next.js Server Actions中传递自定义错误的解决方案
Next.js不允许从Server Components/Server Actions向Client Components传递Error对象,序列化过程中Error会被转换为普通对象,导致客户端无法通过instanceof识别自定义错误类型,同时触发Only plain objects can be passed to Client Components from Server Components. Error objects are not supported.警告。
以下是解决该问题的具体方案:
1. 服务端抛出普通对象而非自定义Error实例
将自定义错误的所有属性封装到普通JavaScript对象中,添加一个标识字段(如isFetchError)用于客户端识别,直接抛出该对象。
修改后的服务端代码:
"use server" async function deleteAddress(contactId: number, addressId: number) { const response = await fetch(`${process.env.BASE_API_URL}/contacts/${contactId}/addresses/${addressId}`, { cache: "no-cache", method: "DELETE" }); if (!response.ok) { // 封装自定义错误信息为普通对象,添加识别标识 throw { isFetchError: true, message: "There was a problem with your request", title: "Something went wrong", severity: "destructive" }; } }
2. 客户端捕获后通过字段判断处理
客户端捕获到的是普通对象,通过检查标识字段和属性来识别自定义错误,进而进行对应处理。
修改后的客户端代码:
"use client" async function handleDelete() { try { await deleteAddress(contactId, addressId) } catch (e) { // 类型检查确保安全访问属性 if (typeof e === 'object' && e !== null && 'isFetchError' in e && e.isFetchError) { // 处理自定义FetchError逻辑 console.log('请求错误:', e.message); // 示例:显示错误提示弹窗 // showErrorToast(e.title, e.message, e.severity); } else { // 处理其他未知错误 console.error('未知错误:', e); } } }
类型安全优化(可选)
如果使用TypeScript,可以定义一个共享的自定义错误类型接口,服务端和客户端都引用该接口,提升类型检查体验:
// 共享类型文件(如types/errors.ts) export interface CustomFetchError { isFetchError: true; message: string; title: string; severity: string; } // 服务端使用 import type { CustomFetchError } from '@/types/errors'; throw { isFetchError: true, message: "There was a problem with your request", title: "Something went wrong", severity: "destructive" } satisfies CustomFetchError; // 客户端使用 import type { CustomFetchError } from '@/types/errors'; catch (e) { const error = e as CustomFetchError; if (error.isFetchError) { // 处理逻辑 } }
内容的提问来源于stack exchange,提问作者hantoren
相关产品推荐
相关产品推荐

