如何修复从 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!',
};
}
我正在尝试使用 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!',
};
}