SvelteKit中Prisma计算字段序列化报错的解决方法咨询
解决SvelteKit中Prisma计算字段导致的序列化错误
我的+page.server.ts抛出如下错误,来自SvelteKit用于序列化数据的devalue包:
Error: Data returned from
loadwhile rendering /[clientId]/companies/[companyId] is not serializable: Cannot stringify POJOs with symbolic keys
问题出在我给PrismaClient添加了计算字段:
const prismaClient = new PrismaClient().$extends({ result: { user: { shortFullName: { needs: { firstName: true, lastName: true }, compute(user) { return `${user.firstName} ${user.lastName}`; } } } } });
执行查询后返回的对象带有符号键(推测是计算字段在运行时添加的):
assignedToUser: { firstName: 'John', lastName: 'Doe', [Symbol(nodejs.util.inspect.custom)]: [Function (anonymous)] } ## 解决方法 ### 方法1:序列化前转成纯普通对象 在`+page.server.ts`的`load`函数里,把查询结果转换成不带符号键的纯POJO。最简单的方式是用JSON序列化再反序列化: ```javascript // +page.server.ts export async function load({ params }) { const company = await prismaClient.company.findUnique({ where: { id: params.companyId }, include: { assignedToUser: true } }); // 转成纯POJO,自动剔除符号键 const sanitizedCompany = JSON.parse(JSON.stringify(company)); return { company: sanitizedCompany }; }
也可以手动构造需要的对象,只保留业务需要的字段,避免冗余:
const sanitizedCompany = { ...company, assignedToUser: { firstName: company.assignedToUser.firstName, lastName: company.assignedToUser.lastName, shortFullName: company.assignedToUser.shortFullName } };
方法2:查询时显式指定返回字段
用Prisma的select语法明确指定要返回的字段(包括计算字段),这样返回的对象只会包含你指定的属性,不会带出符号键:
const company = await prismaClient.company.findUnique({ where: { id: params.companyId }, select: { id: true, name: true, assignedToUser: { select: { firstName: true, lastName: true, shortFullName: true // 显式包含计算字段 } } } });
方法3:自定义devalue序列化规则(不推荐)
虽然可以扩展devalue的逻辑来处理符号键,但这种方法复杂度高,还可能和SvelteKit的版本更新冲突,一般不建议使用。
内容的提问来源于stack exchange,提问作者tbdrz
相关产品推荐
相关产品推荐

