如何使用GraphQL和Mongoose处理多个验证错误?

时间:2019-07-20 12:54:40

标签: javascript mongoose graphql apollo-server

人。我正在使用Apollo Server使用用户注册解析器,但不确定如何处理从Mongoose的模型验证中抛出的多个错误。

截至目前,我已经使用此当前模型来存储我正在使用的这个小应用程序的用户:

const userSchema = new Schema({
    username: {
        type: String,
        required: true,
        unique: true
    },
    email: {
        type: String,
        required: true,
        validate: {
            validator: (value) => validator.isEmail(value),
            message: (data) => `${data.value} is not a valid e-mail address!`
        },
        unique: true
    },
    digest: String,
});

我正在使用mongoose-unique-validator来确保usernameemail是唯一的,否则,将引发错误。

问题是,我不知道如何处理同时抛出的这两个错误(如果文档为emailusername.save()都无效d)。

我使用GraphQL Playground测试了这种情况,这是当这些验证都被触发(都失败)时得到的:

{
  "errors": [
    {
      "message": "Couldn't create user: ValidationError: email: Error, expected `email` to be unique. Value: `test@test2.com`, username: Error, expected `username` to be unique. Value: `test4`",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "createUser"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Couldn't create user: ValidationError: email: Error, expected `email` to be unique. Value: `test@test2.com`, username: Error, expected `username` to be unique. Value: `test4`",
            "    at /Users/trashpanda/Projects/roma/server/src/graphql/resolvers.js:19:27",
            "    at processTicksAndRejections (internal/process/task_queues.js:89:5)"
          ]
        }
      }
    }
  ],
  "data": {
    "createUser": null
  }
}

从我对文档的了解来看,最理想的情况是我希望收到一系列可以迭代的错误,但是我不确定如何实现,因为Mongoose只是将两个验证错误都连接到一条消息中被作为一个单一错误抛出。

以下是解析器:

import bcrypt from 'bcrypt';
import { ApolloError } from 'apollo-server-express';
import validator from 'validator';
import { User } from '../db/db';

const resolvers = {
    Mutation: {
        createUser: (_, args) => {
            const {username, password, email} = args;
            return bcrypt.hash(password, 12)
                .then((digest) => {
                     const doc = { username, digest, email };
                     const newUser = new User(doc);
                     return newUser.save();
                })
                .then((doc) => {
                    return doc;
                })
                .catch((err) => {
                    throw new ApolloError(`Couldn't create user: ${err}`);
                });
        }
    }
};

export default resolvers;

就我在.catch()的Promise中使用.save()的方式而言,我是否需要与Apollo Server合作?我很困惑。我只知道我希望能够在客户端上独立检查两个错误(例如突出显示输入字段等),所以我想我需要让它抛出一系列错误,而不仅仅是一个错误“捆绑”一个。

有想法吗?

0 个答案:

没有答案