0

¿Como enviar un código de estado http dependiendo de si hay un error o no?, mas específicamente el error que quiero controlar es si el objeto que envían al servidor cumple con ciertas validaciones

Lo que intenté:

Rutas:

const express = require('express')
const router = express.Router()
const dataBase = require('../database')
const employee = require('../models/Employee')


router.post('/addEmployee', async (req,res,next)=>{
    try{
        const obj = await req.body
        const addEmployee = await employee.addEmployee(obj,dataBase.db)
        res.sendStatus(200)
        next()


    }catch(e){
        res.sendStatus(500)
    }

})

module.exports = router

Employee Antiguo:

const MongoDB = require("mongodb");

const addEmployee = function (myobj, db) {
  try {
    const collection = db.collection("employees");

    collection.insertOne(myobj, (err, res) => {
        if(err){
            console.log("Ocurrio un error al insertar el usuario".red,err.errmsg)
            return
        }
        const id = res.ops[0]._id;
        var date = new Date();
        const dateFormat = `Fecha: ${date.getUTCDate()}/${date.getUTCMonth()}/${date.getUTCFullYear()} Hora: ${date.getUTCHours()}:${date.getUTCMinutes()}:${date.getUTCSeconds()} UTC`;
  
        collection.findOneAndUpdate(
          { _id: id },
          { $set: { created_At: dateFormat } }
        );
    });
  } catch (error) {
        console.log("OCURRIO UN ERRO AL INSERTAR EL USUARIO".red, error);
        throw error
  }
};

const employee = {};
employee.addEmployee = addEmployee;
module.exports = employee;

Employee Nuevo:

const MongoDB = require("mongodb");

class UserError extends Error {
  constructor(message) {
      super();
      this.message = message;
      this.errorCode = 500;
  }
}

const addEmployee = function (myobj, db) {
  try {
    const collection = db.collection("employees");
    collection.insertOne(myobj, (err, res) => {
        if(err){
          throw new UserError('Ocurrio un error al insertar el usuario');
        }
        const id = res.ops[0]._id;
        var date = new Date();
        const dateFormat = `Fecha: ${date.getUTCDate()}/${date.getUTCMonth()}/${date.getUTCFullYear()} Hora: ${date.getUTCHours()}:${date.getUTCMinutes()}:${date.getUTCSeconds()} UTC`;
  
        collection.findOneAndUpdate(
          { _id: id },
          { $set: { created_At: dateFormat } }
        );
    });
  } catch (e) {
      if(e instanceof UserError){
        throw(e);
      }else{
        console.log(e)
      }
  }
};

const employee = {};
employee.addEmployee = addEmployee;
module.exports = employee;

Error que lanza (en consola, y sigue devolviendo status 200) esta ultima versión de employee al hacer una petición que no cumple las validaciones

      throw err;
      ^

UserError: Ocurrio un error al insertar el usuario
    at C:\Users\Franco\Desktop\APPS BACKEND AND FRONTEND\ADMINISTRADOR DE EMPLEADOS\backend\src\models\Employee.js:16:17    
    at executeCallback (C:\Users\Franco\Desktop\APPS BACKEND AND FRONTEND\ADMINISTRADOR DE EMPLEADOS\backend\node_modules\mongodb\lib\operations\execute_operation.js:70:5)
    at C:\Users\Franco\Desktop\APPS BACKEND AND FRONTEND\ADMINISTRADOR DE EMPLEADOS\backend\node_modules\mongodb\lib\operations\insert_one.js:28:35
    at handleCallback (C:\Users\Franco\Desktop\APPS BACKEND AND FRONTEND\ADMINISTRADOR DE EMPLEADOS\backend\node_modules\mongodb\lib\utils.js:128:55)
    at C:\Users\Franco\Desktop\APPS BACKEND AND FRONTEND\ADMINISTRADOR DE EMPLEADOS\backend\node_modules\mongodb\lib\operations\common_functions.js:265:14
    at handler (C:\Users\Franco\Desktop\APPS BACKEND AND FRONTEND\ADMINISTRADOR DE EMPLEADOS\backend\node_modules\mongodb\lib\core\sdam\topology.js:913:24)
    at C:\Users\Franco\Desktop\APPS BACKEND AND FRONTEND\ADMINISTRADOR DE EMPLEADOS\backend\node_modules\mongodb\lib\cmap\connection_pool.js:352:13
    at handleOperationResult (C:\Users\Franco\Desktop\APPS BACKEND AND FRONTEND\ADMINISTRADOR DE EMPLEADOS\backend\node_modules\mongodb\lib\core\sdam\server.js:489:5)
    at MessageStream.messageHandler (C:\Users\Franco\Desktop\APPS BACKEND AND FRONTEND\ADMINISTRADOR DE EMPLEADOS\backend\node_modules\mongodb\lib\cmap\connection.js:270:5)
    at MessageStream.emit (events.js:311:20) {
  message: 'Ocurrio un error al insertar el usuario',
  errorCode: 500
}
[nodemon] app crashed - waiting for file changes before starting...
Franco
  • 1,075
  • 4
  • 20

2 Answers2

1

Desde tu modelo "employee" estás manejando el error y mostrándolo con un console.log().

Si no relanzas el error no va a llegar nunca al otro manejador. Por ejemplo, podrías hacer algo similar a esto:

class UserError extends Error {
    constructor(message) {
        super();
        this.message = message;
        this.errorCode = 500;
    }
}



try {
    const err = true;
    if(err)
        throw new UserError('Ocurrio un error al insertar el usuario');

    // Continuas la ejecución de tu código
} catch (e) {
    if(e instanceof UserError)
        throw(e); //Relanzas el error para que lo capture el siguiente manejador
    else 
        console.log(e);
}

De esa forma, si es un error que quieres mostrar al usuario, lo devuelves con un error de "UserError". De lo contrario, cualquier error referente al funcionamiento del código se mostrará por consola.

Hiperion
  • 151
  • 8
  • Aun sigue sin funcionar, no manda el error hacia las rutas para que lo maneje desde allí, sigo obteniendo status 200 cuando realizo la petición ya sea exitosa o tire un error en consola – Franco May 17 '20 at 15:24
  • Pon también el nuevo código debajo del antiguo, para que podamos ver donde está el error. – Hiperion May 17 '20 at 17:34
  • Listo, ya actualize – Franco May 17 '20 at 17:49
  • 1
    Vale, el problema es que estás utilizando un try catch con código asíncrono. Tienes dos opciones; sacar el código del callback (La función insertOne() debería devolver el id, en caso de error relanzará una excepción) o utilizar promesas para manejar el error, en vez de un try catch. – Hiperion May 17 '20 at 18:28
  • ¡Gracias!, tengo una duda mas, ¿por que no puedo utilizar callbacks con try catch no se puede tener 2 manejadores de errores o como es? – Franco May 17 '20 at 19:44
  • 1
    No, es porque el manejo del error y la ejecución del callback no suceden en el mismo tiempo, el manejador no va a esperar a que finalice la ejecución de la función asíncrona. Mira la diferencia entre código asíncrono y sincrono: https://es.stackoverflow.com/a/277693/38064 – Hiperion May 18 '20 at 15:49
0

Como comenta Epbulist el problema es que estas haciendo un console.log del error entonces ahí termina el flujo.

Tendrías que hacer lo siguiente:

const addEmployee = function (myobj, db) {
  try {
    const collection = db.collection("employees");

    collection.insertOne(myobj, (err, res) => {
        if(err){
            console.log("Ocurrio un error al insertar el usuario".red,err.errmsg)
            return
        }
        const id = res.ops[0]._id;
        var date = new Date();
        const dateFormat = `Fecha: ${date.getUTCDate()}/${date.getUTCMonth()}/${date.getUTCFullYear()} Hora: ${date.getUTCHours()}:${date.getUTCMinutes()}:${date.getUTCSeconds()} UTC`;

        collection.findOneAndUpdate(
          { _id: id },
          { $set: { created_At: dateFormat } }
        );
    });
  } catch (error) {
        console.log("OCURRIO UN ERRO AL INSERTAR EL USUARIO".red, error);
        // Aquí tienes que lanzar el error hacia arriba para que lo pueda capturar el router.
        throw error;
  }
};

const employee = {};
employee.addEmployee = addEmployee;
module.exports = employee;
j0nl1
  • 99
  • 2
  • Hola, ya lo intente pero no funciona me sigue imprimiendo el error en consola pero no lo manda a las rutas para que maneje el error allí también – Franco May 17 '20 at 15:20