Graphql: I cannot stop the Node execution and return the Error (Business Error)

Asked

Viewed 143 times

-1

I’m trying to create some queries and mutations, on Node with Graphql. I’ve tried how to solve the problem and I can’t find a solution. I wonder if someone could help me?

In the project I put the dependencies graphql-yoga and Mongoose.

I’m setting up a Mutation that "draws" money from an "account". I can execute by decreasing the value of the balance in the database. The problem is when you try to withdraw larger amount than the account balance. I needed at that time to show error that you do not have enough balance.

The Application is only displaying NULL balance, and does not display the error message. They know how to include in the Mutation return??

Everything else is working.

Below the code of the file resolvers.js (in Mutation withdraw, after itentify the insufficient balance error, I error, the application leaves the stream and enters the catch. But I don’t know how to log in to the error message. I only played on the console.

const Conta = require("./Conta");
let newSaldo;

module.exports = {
  Query: {
    contas: () => Conta.find(),
    conta: (root, { numero }) => Conta.findOne({ numero }),
  },

  Mutation: {
    createConta: (root, { numero, saldo, cliente }) => Conta.create({ numero, saldo, cliente }),

    depositar: (root, { numero, valor }) => Conta.findOne({numero})
                                            .then(() => Conta.updateOne({numero},{$inc:{saldo : valor}}))
                                            .then(() => Conta.findOne({numero})),

    sacar: (root, { numero, valor }) => Conta.findOne({numero})
                                        .then(value => {
                                            newSaldo = value.saldo
                                            if (valor > value.saldo) {
                                                throw new Error("Saldo Insuficiente")
                                            }
                                            else{
                                                newSaldo = value.saldo - valor
                                            }
                                        }) 
                                        .then(() => Conta.updateOne({numero},{$set:{saldo: newSaldo}}))
                                        .then(() => Conta.findOne({numero}))
                                        .catch((err) => console.log(err))                  
  },
}

schema.graphql file

type Conta {
  id: ID!
  numero: String!
  saldo: Float!
  cliente: String!
}

type Query {
  contas: [Conta!]
  conta(numero: Int!): Conta
}

type Mutation {
  createConta(numero: Int!, saldo: Float!, cliente: String!): Conta
  depositar(numero: Int!, valor: Float!): Conta
  sacar(numero: Int!, valor: Float!): Conta
}

Below the execution of Mutation, with return, to an account that does not have enough balance. Displaying NULL Balance. I need to return the error message on this screen. They can help??

inserir a descrição da imagem aqui

  • Have you ever tried to create a Promise and return it in the resolve? I do not know if the Promise.reject will have effect inside the then

  • Something thus

  • Adding, below the promisse line.Reject, a catch, I stopped receiving the Node error (Unhandledpromiserejectionwarning). However, I still don’t know how to play this error for Mutation’s return.I will update the code in the question

  • With that you prevent the error to be propagated to solve it

  • So how should I treat it? Any idea? I accept the business mistake, but I can never display it in return.

  • I always return to Promise pro resolver, if error shows that failed, in case of success it brings the data

  • I made an error, but it is a business error. So no error shows me the account balance. I need you to display an error/insufficient balance message

  • I was able to create an error from the rest of the stream. However, it displays a response with NULL balance, I need it to display the error message. How can I do this in catch??? I changed the body of my question with new code

  • Fez of that form, I only let the error go up, I do not believe that has to return the error, as if it was the result of the query itself, it will return a null value, since there is nothing to return, the error comes separate. Here an address with the code working

Show 4 more comments

1 answer

0


Mutation can only return something in the format that was set within your schema, when you bump into an error, the return will be null and next to it a list of errors that occurred, will have the following format:

{
  "data": {
    "sacar": null
  },
  "errors": [
    {
      "message": "Saldo Insuficiente",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "sacar"
      ]
    }
  ]
}

In order for graphql to know that the error has occurred you need to let the error go up:

const Conta = require("./Conta");
let newSaldo;

module.exports = {
    Query: {
        contas: () => Conta.find(),
        conta: (root, {
            numero
        }) => Conta.findOne({
            numero
        }),
    },

    Mutation: {
        createConta: (root, {
            numero,
            saldo,
            cliente
        }) => Conta.create({
            numero,
            saldo,
            cliente
        }),

        depositar: (root, {
                numero,
                valor
            }) => Conta.findOne({
                numero
            })
            .then(() => Conta.updateOne({
                numero
            }, {
                $inc: {
                    saldo: valor
                }
            }))
            .then(() => Conta.findOne({
                numero
            })),

        sacar: (root, {
                numero,
                valor
            }) => Conta.findOne({
                numero
            })
            .then(value => {
                newSaldo = value.saldo
                if (valor > value.saldo) {
                    throw new Error("Saldo Insuficiente")
                } else {
                    newSaldo = value.saldo - valor
                }
            })
            .then(() => Conta.updateOne({
                numero
            }, {
                $set: {
                    saldo: newSaldo
                }
            }))
            .then(() => Conta.findOne({
                numero
            }))
    },
}

Remove the catch is enough, here a functional example, here the source code for reference

Note: I did not implement the bank part, the example works with the following Mutation:

mutation {
  sacar(numero: 100, valor: 100) {
    saldo
  }
}

mutation {
  sacar(numero: 100, valor: 101) {
    saldo
  }
}
  • In this way you have served me correctly. Thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.