NestJS解析器错误处理复用方案咨询
实现方案
当然有可行的方案,最实用的方式是把重复的检查逻辑抽成公共工具函数,再通过高阶函数包装你的Mutation解析器,彻底消除重复代码。下面是具体实现步骤:
1. 抽离公共检查逻辑
先把管理员权限检查、用户存在性检查这两块重复代码,抽成独立的工具函数(可以单独放在userUtils.js/ts文件里):
// userUtils.js // 检查当前用户是否有管理员权限 export const checkAdminPermission = async (context) => { const currentUser = context.currentUser; if (!currentUser || !currentUser.isAdmin) { throw new Error("无管理员权限,无法执行此操作"); } }; // 检查目标用户是否存在,存在则返回用户对象 export const checkUserExists = async (userId, prisma) => { const user = await prisma.user.findUnique({ where: { id: userId } }); if (!user) { throw new Error(`ID为${userId}的用户不存在`); } return user; };
2. 编写高阶函数包装解析器
写一个高阶函数,它接收Mutation的核心业务逻辑作为参数,先统一执行前置检查,再运行核心逻辑:
// userResolvers.js import { checkAdminPermission, checkUserExists } from './userUtils'; // 高阶函数:封装管理员权限+目标用户存在性检查 const withUserAdminCheck = (resolveFn) => { return async (parent, args, context, info) => { // 先执行权限检查 await checkAdminPermission(context); // 再检查目标用户是否存在,并把用户对象传入后续逻辑 const targetUser = await checkUserExists(args.userId, context.prisma); // 把查询到的用户追加到参数中,避免核心逻辑重复查询 return resolveFn(parent, { ...args, targetUser }, context, info); }; };
3. 改造现有Mutation解析器
把原来写满重复检查的解析器,替换成用高阶函数包装的形式,核心逻辑只保留业务代码:
// 改造前的updateUser(冗余版本) const updateUser = async (parent, args, context, info) => { // 重复的权限检查 const currentUser = context.currentUser; if (!currentUser || !currentUser.isAdmin) { throw new Error("无管理员权限"); } // 重复的用户存在检查 const user = await context.prisma.user.findUnique({ where: { id: args.userId } }); if (!user) { throw new Error("用户不存在"); } // 核心业务逻辑 return context.prisma.user.update({ where: { id: args.userId }, data: args.data }); }; // 改造后的updateUser(精简版本) const updateUser = withUserAdminCheck(async (parent, args, context, info) => { // 直接用高阶函数传入的targetUser,只写业务逻辑 return context.prisma.user.update({ where: { id: args.targetUser.id }, data: args.data }); }); // 其他现有Mutation同理改造 const deleteUser = withUserAdminCheck(async (parent, args, context, info) => { return context.prisma.user.delete({ where: { id: args.targetUser.id } }); }); const markInactive = withUserAdminCheck(async (parent, args, context, info) => { return context.prisma.user.update({ where: { id: args.targetUser.id }, data: { isActive: false } }); }); const banUser = withUserAdminCheck(async (parent, args, context, info) => { return context.prisma.user.update({ where: { id: args.targetUser.id }, data: { isBanned: true } }); });
4. 新增Mutation直接复用
新增的两个更新类Mutation,直接用withUserAdminCheck包装核心逻辑即可,完全不用再写重复检查:
// 新增的updateUserProfile const updateUserProfile = withUserAdminCheck(async (parent, args, context, info) => { return context.prisma.user.update({ where: { id: args.targetUser.id }, data: { profile: args.profileData } }); }); // 新增的updateUserRole const updateUserRole = withUserAdminCheck(async (parent, args, context, info) => { return context.prisma.user.update({ where: { id: args.targetUser.id }, data: { role: args.newRole } }); });
扩展说明
- 如果部分Mutation只需要管理员权限检查、不需要用户存在性检查(比如创建用户),可以拆分出更细的高阶函数(比如
withAdminCheck),按需组合使用。 - 若使用TypeScript,可以给高阶函数添加类型定义,让参数和返回值的类型更严谨。
内容的提问来源于stack exchange,提问作者Lionel B
相关产品推荐
相关产品推荐

