0

I am trying to return specific status codes such as, 409 Conflict. I have used the Model#save docs

Edit: I am not trying to solve the error, it is deliberate.

According to the docs, there is three parameters on the callback: err, product, and numAffected.

EDIT: I wrote this code wrong and I edited. Either way, I got an excellent answer from Ryan.

  app.post('/skill', (req, res) => {
    const skill = new Skill({some_duplicate_object});
    skill.save((err, product, numAffected) => {
        console.log("Error: ", err);

    });

NOT my console.log, in the Mocha test cli, I get an error:

(node:19760) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 5): ValidationError: Path `name` is required.



By playing around and shear luck, I did this: This is NOT in the mongoose docs and is my main reason for writing this post.

  app.post('/skill', (req, res) => {
    const skill = new Skill({});
    skill.save()
      .then((err, product, numAffected) => {
        console.log("Nothing displayed here");
    }, (err) => {
      console.log(err.errors);
    });

Even though this is not in the docs, it shows the error I want. As someone that is REALLY trying to use official docs more, I find it so hard to understand what is really going on. Why does this work and if it is in the docs, where would this info be?

{ name: 
   { MongooseError: Path `name` is required.
       at ValidatorError (/home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/error/validator.js:24:11)
       at validate (/home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/schematype.js:706:13)
       at /home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/schematype.js:752:11
       at Array.forEach (native)
       at SchemaString.SchemaType.doValidate (/home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/schematype.js:712:19)
       at /home/codeamend/Coding/projects/portfolio/work/CodeAmend.Com/backend/node_modules/mongoose/lib/document.js:1408:9
       at _combinedTickCallback (internal/process/next_tick.js:73:7)
       at process._tickCallback (internal/process/next_tick.js:104:9)
     message: 'Path `name` is required.',
     name: 'ValidatorError',
     properties: 
      { type: 'required',
        message: 'Path `{PATH}` is required.',
        validator: [Function],
        path: 'name',
        value: undefined },
     kind: 'required',
     path: 'name',
     value: undefined,
     reason: undefined } }

Extra info:

  "devDependencies": {
    "chai": "^3.5.0",
    "mocha": "^2.4.5",
    "request": "^2.81.0",
    "supertest": "^3.0.0"
  },
  "dependencies": {
    "body-parser": "^1.17.1",
    "express": "^4.15.2",
    "mongoose": "^4.9.2"
  }
Michael Bruce
  • 10,567
  • 2
  • 23
  • 31
  • 2
    You are seeing the error in Mocha because there is an error than isn't in a `catch()`. You need `skill.save().then(function(result){}).catch(function(err){})` – doublesharp Mar 30 '17 at 16:36
  • 1
    It also looks like `skill` has some validations set up, the error i complaining that you aren't passing a `PATH` value. – doublesharp Mar 30 '17 at 16:36
  • you have set the name field required in the schema, so the validation error occurs when you try to save the document as no name is being provided – parwatcodes Mar 30 '17 at 16:38

2 Answers2

1

Your problem is two fold, and both of the errors you are getting are telling you exactly what is wrong. The source of your troubles is lack of understanding (not trying to pick on you). This is kind of the same as if you were a beginner at electronics and I told your that a tube is biased improperly and you said "I don't understand" - well, you need to learn about tubes then because I just described to you the exact problem with your circuit.

1. Promise error - UnhandledPromiseRejectionWarning: Unhandled promise rejection.... This cannot be more descript. Promises are either 1) resolved or 2) rejected. If you fail to "handle" the rejected case, you will get an error. Handling a rejected promise can happen one of two ways:

// pass a 2nd function to `.then()`:
somePromise.then(function (result) {
  // promise was "resolved" successfully
}, function (err) {
  // Promise was "rejected"
});

// use `.catch()` - this is preferred in my opinion:
somePromise.then(function (result) {
  // promise was "resolved" successfully
}).catch(function (err) {
  // Promise was "rejected"
});

Using either of the above scenarios means you "handled" the promise rejection correctly.

2. Database validation - Path 'name' is required.. This literally means that you have a required path called "name" which is required (meaning, it must have a value). So looking at your code it's pretty obvious:

const skill = new Skill({});
skill.save() //-> results in error

This is fixed by adding all required data before saving:

const skill = new Skill({ name: "Jason" });
skill.save() //-> yay, no error
Ryan Wheale
  • 26,022
  • 8
  • 76
  • 96
  • It looks like I was not treating this like a Promise object. You are right, I did not understand. So my second function argument was the 'rejected' parameter of the Promise object? Which is essentually the same as .catch((err)=>{})? – Michael Bruce Mar 30 '17 at 18:37
  • Yes, that is correct. I think they assume that you know how to use a promise properly, otherwise their examples would nearly double in size. – Ryan Wheale Mar 30 '17 at 20:36
  • Ryan, I wrote the first example wrong and I fixed it. My concern came from the lack of error by the save() method. I only got an error when adding the second function argument (Now I see that this was a promise object and they are completely different). If I knew what I knew now, I would have asked the question completely differently. – Michael Bruce Mar 30 '17 at 20:47
  • No worries - and I wasn't trying to be like "you know nothing you idiot!!" ;) Promises can be confusing. – Ryan Wheale Mar 30 '17 at 20:50
0

You're not handling the promise rejection.

Change this:

.then((err, product, numAffected) => {
    console.log("Error: ", err);
});

to this:

.then((result) => {
    console.log('Result:', result);
}).catch((error) => {
    console.log('Error:', error);

Of course change what happens in the callbacks to whatever you need.

See this answer for more general info on unhandled rejection:

Community
  • 1
  • 1
rsp
  • 107,747
  • 29
  • 201
  • 177