如何修复从 apollo 服务器向前端发送错误

How to fix the sending of errors to frontend from apollo server

我正在尝试使用 Apollo 和 React 制作注册表单,但在处理请求后的错误时遇到了问题。

问题是这样发生的:当我尝试注册已经存在的用户时,我在控制台中收到错误 That username is already in use! 但我的服务器发送的错误是

GraphQL error: Cannot return null for non-nullable field Mutation.registerUser.

当我尝试 return 只有成功时才会发生这种情况。

如果我尝试 return 任何一种方式,我都会在控制台上收到错误,但前端接收到它是成功的,并且会发生下一个逻辑(在我的情况下重定向到另一个页面)

我想弄清楚的是如何将正确的错误消息发送到前端?因为没有所有错误都在后端抛出,我只在我的控制台中看到它们,但 Apollo 发送了不同的错误。

这是我的代码

typeDefs.ts

module.exports = gql`
  type Response {
    message: String!
  }
  input RegisterInput {
    username: String!
    password: String!
  }
  type Mutation {
    registerUser(registerInput: RegisterInput): Response!
  }
`;

前端突变

import gql from 'graphql-tag';

const REGISTER_USER = gql`
  mutation RegisterUser($registerInput: RegisterInput) {
    registerUser(registerInput: $registerInput) {
      message
    }
  }
`;

export { REGISTER_USER };

后端突变

Mutation: {
    registerUser(_, { registerInput }) {
      const { username, password } = registerInput;
      const saltRounds = 12;

      console.log(123);

      if (!username || !password) {
        throw new Error('Username and password are required!');
      }
      if (password.length < 6) {
        throw new Error('Password must be minimum 6 characters!');
      }

      UserModel.findOne({ username }, (error: string, existingUser: User) => {
        if (error) {
          throw new Error(error);
        }
        if (existingUser) {
          throw new Error('That username is already in use!');
        } else if (!error && !existingUser) {
          bcrypt.genSalt(saltRounds, (error: string, salt: string) => {
            if (error) {
              throw new Error(error);
            }
            bcrypt.hash(password, salt, (error: string, hash: string) => {
              if (error) {
                throw new Error(error);
              } else {
                const newUser = new UserModel({
                  username,
                  password: hash,
                });

                newUser.save((error: string, user: User) => {
                  if (error) {
                    throw new Error(error);
                  } else {
                    return {
                      message: 'Registered successfully',
                    };
                  }
                });
              }
            });
          });
        }
      });
    },

我最后添加了这个:

type SuccessRespose {
    message: String!
  }

type Mutation {
    registerUser(registerInput: RegisterInput): SuccessRespose!
  }

在解析器中

const user = await UserModel.findOne(
        { username },
        (error: string, existingUser: User): void => {
          if (error) {
            throw new Error(error);
          }
          if (!error && !existingUser) {
            bcrypt.genSalt(saltRounds, (error: string, salt: string) => {
              if (error) {
                throw new Error(error);
              }
              bcrypt.hash(password, salt, (error: string, hash: string) => {
                if (error) {
                  throw new Error(error);
                } else {
                  const newUser = new UserModel({
                    username,
                    password: hash,
                  });

                  newUser.save((error: string, user: User) => {
                    if (error) {
                      throw new Error(error);
                    } else {
                    }
                  });
                }
              });
            });
          }
        },
      );

      if (user) {
        throw new Error('That username is already in use!');
      } else {
        return {
          message: 'Registration successful!',
        };
      }