Tengo un método de login de sesión que devuelve una Promesa a GraphQL para resolver. Si el usuario se encuentra y se autentica, lo resuelve y funciona como debería. Sin embargo, si la cuenta no existe o no se pudo resolver, la promesa se rechaza con un mensaje Invalid credentials. Esto está bien, pero parece que recibo un error de GraphQL cuando esto sucede, así que creo que estoy enviando a GraphQL algo que no esperaba.
Aquí está mi código: mutaciones.js :
login: { type: UserType, args: { email: { type: GraphQLString }, password: { type: GraphQLString } }, resolve(parentValue, { email, password }, req) { return AuthService.login({ email, password, req }) } }AuthService.login :
function login({ email, password, req }) { return new Promise((resolve, reject) => { passport.authenticate('local', (err, user) => { if (!user) { reject('Invalid credentials.') } req.login(user, () => resolve(user)); })({ body: { email, password } }); }); }El error de GraphQL que recibo es este:
{ "errors": [ { "message": "Unexpected error value: \"Invalid credentials.\"", "locations": [ { "line": 2, "column": 3 } ], "path": [ "login" ] } ], "data": { "login": null } } Pero creo que si estuviera devolviendo un GraphQLFieldResolver adecuado, ¿no obtendría un resultado de error mucho más simple? ¿Como solo una matriz o (en este caso una matriz de uno) mensajes de error?
Por ejemplo, digamos que cambio el resolver a esto:
resolve(parentValue, { email, password }, req) { throw "Error!" // return AuthService.login({ email, password, req }) } Recibo el mensaje de error "message": "Unexpected error value: \"Error!\"" . ¿No debería recibir un "message": "Error!" ¿en cambio? ¿Es ese un estándar de GraphQL para devolver mensajes de error con Unexpected error value: X ?
El problema es que está devolviendo una promesa que se rechaza con una cadena, en lugar de un objeto de Error . O en su versión más simple, está throw una cadena en lugar de un objeto Error .
Simplemente no hagas eso.
Dudo que haya algo en el estándar GraphQL sobre esto (después de todo, esta es la implementación, no el protocolo API), es solo graphql.js esperando objetos de Error (para que pueda enviar stacktraces, etc. en modo de desarrollo) y quejándose de no Error excepciones con un mensaje de " Valor de error inesperado ".
Para arreglar su código, use
function login({ email, password, req }) { return new Promise((resolve, reject) => { passport.authenticate('local', (err, user) => { if (!user) { reject(new Error('Invalid credentials.')) } // ^^^^^^^^^^ ^ req.login(user, () => resolve(user)); })({ body: { email, password } }); }); } o incluso mejor simplemente reject(err) .