Я пробую свои силы в (Apollo) GraphQL на стороне сервера, и у меня возникла, вероятно, глупая проблема. Я пытаюсь зарегистрировать пользователя, но по-прежнему получаю сообщение об ошибке, показанное на изображении ниже. В чем проблема? Игнорируйте очень простой процесс аутентификации, так как я просто тестирую GraphQl
Вот соответствующие фрагменты кода:
Схема
export default `
type User {
id: ID!
name: String!
email: String!
}
type Query {
allUsers: [User]
currentUser: User
}
type Mutation {
createAccount(name: String!, email: String!, password: String!): User
loginUser(email: String!, password: String!): User
updatePassword(email: String!, password: String!, newPassword: String!): User
deleteAccount(email: String!, password: String!): User
}
`
Резольверы
createAccount: async (
parent,
{ name, email, password },
{ User },
info
) => {
try {
// Check for invalid (undefined) credentials
if (!name || !email || !password) {
return 'Please provide valid credentials';
}
// Check if there is a user with the same email
const foundUser = await User.findOne({ email });
if (foundUser) {
return 'Email is already in use';
}
// If no user with email create a new user
const hashedPassword = await bcrypt.hash(password, 10);
await User.insert({ name, email, password: hashedPassword });
const savedUser = await User.findOne({ email });
return savedUser;
} catch (error) {
return error.message;
}
},



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Самая большая проблема с вашим преобразователем заключается в том, что в любом количестве сценариев вместо возврата объекта User вы возвращаете строку. В вашей схеме указано, что createAccount может возвращать User или null (если бы это был User!, он не мог бы иметь значение NULL, и тогда null также не был бы допустимым типом).
Когда вы возвращаете строку в свой распознаватель, поскольку он ожидает объект, он преобразует ее в один и затем начинает искать свойства User для этого объекта (например, name и email). Эти свойства не существуют, и поскольку они являются ненулевыми свойствами в вашем объекте User, возврат для них null / undefined приводит к ошибке.
Ваш преобразователь, вероятно, должен просто выдавать любые ошибки, которые ему нужно выдать. Затем они будут возвращены как часть массива errors в вашем ответе. Например:
// Check if there is a user with the same email
const foundUser = await User.findOne({ email })
if (foundUser) throw new Error('Email is already in use')
// If no user with email create a new user
const hashedPassword = await bcrypt.hash(password, 10);
await User.insert({ name, email, password: hashedPassword });
const savedUser = await User.findOne({ email });
return savedUser;
Теперь, если у вас есть дубликат электронного письма, ответ будет выглядеть примерно так:
{
"data": {
"createAccount": null
},
"errors": [
{
"message": "Email is already in use",
"locations": [
{
"line": 4,
"column": 3
}
],
"path": [
"createAccount"
]
}
]
}
Если вы хотите управлять тем, как ваши ошибки отображаются на клиенте, вам следует использовать параметры конфигурации formatError или formatResponse для промежуточного программного обеспечения сервера Apollo. Также рекомендуется использовать настраиваемые ошибки, позволяя добавлять настраиваемые свойства, такие как code, для более легкого определения типа ошибки на стороне клиента.
Наконец, нет необходимости проверять, определены ли имя, адрес электронной почты или пароль внутри вашего преобразователя - в вашей схеме эти входы уже отмечены как ненулевые, что означает, что GraphQL автоматически вернет ошибку, если какой-либо из них отсутствует.
ПРИВЕТ, ДАНИЭЛЬ, ВЫ ГОВОРИТЕ, КАК НЕ ДОЛЖНЫ ВОЗВРАЩАТЬ строку? У меня та же проблема
Большое спасибо за помощь. Я заставил его работать, следуя вашему совету.