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

Nexus resolver返回ApolloError的类型安全实现及最佳实践问询

方案1:直接抛出错误(最推荐)

Apollo Server 会自动捕获 resolver 中抛出的错误,放入响应的errors字段,不需要将错误作为返回值返回,因此你根本不需要把错误类型加入Nexus的返回类型定义,完美解决类型冲突问题。
修改后的代码如下:

export const confirmEmail = mutationField('confirmEmail', {
  // 只定义成功的返回类型即可
  type: nonNull(Boolean),
  args: {
    email: nonNull(stringArg()),
    code: nonNull(stringArg()),
  },
  resolve: async (_, args, ctx) => {
    const user = await ctx.prisma.user.findUnique({
      where: {
        email: args.email,
      },
    })

    if (!user) {
      // 直接抛出错误而不是返回
      throw new ApolloError('User does not exists', 'BAD_USER_INPUT')
    }
    await sendEmail(
      'jonashiltl2003@gmail.com',
      `<p>Your confirmation code is: </p> <b>${args.code}</b>`,
      'Confirmation Code',
    )
    return true
  },
})

这种方案完全符合GraphQL的规范,错误统一走顶级errors字段,客户端可以统一处理,同时完全满足TS类型安全要求,没有类型报错。

方案2:定义业务错误联合类型(适合需要把错误放到data字段的场景)

如果你希望业务错误和数据一起放到data字段返回,不走全局errors,可以用Nexus的unionType定义成功和错误的联合返回类型:
首先定义联合类型:

// 先定义错误类型
const UserNotFoundError = objectType({
  name: 'UserNotFoundError',
  definition(t) {
    t.nonNull.string('message')
    t.nonNull.string('code')
  }
})

// 定义返回结果联合类型
const ConfirmEmailResult = unionType({
  name: 'ConfirmEmailResult',
  definition(t) {
    t.members('Boolean', 'UserNotFoundError')
  },
  resolveType(value) {
    if (value instanceof ApolloError) {
      return 'UserNotFoundError'
    }
    return 'Boolean'
  }
})

然后mutation的type直接用这个联合类型即可:

export const confirmEmail = mutationField('confirmEmail', {
  type: nonNull(ConfirmEmailResult),
  args: {
    email: nonNull(stringArg()),
    code: nonNull(stringArg()),
  },
  resolve: async (_, args, ctx) => {
    const user = await ctx.prisma.user.findUnique({
      where: {
        email: args.email,
      },
    })

    if (!user) {
      return new ApolloError('User does not exists', 'BAD_USER_INPUT')
    }
    await sendEmail(
      'jonashiltl2003@gmail.com',
      `<p>Your confirmation code is: </p> <b>${args.code}</b>`,
      'Confirmation Code',
    )
    return true
  },
})

这种方案适合需要细分业务错误、让客户端在data层级处理错误的场景,同样完全保证类型安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 01:09:04