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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:20:48