I use mongoose and bluebird as a promise framework.
Everytime I use "save" or "remove" I get this error :
Warning: a promise was created in a handler but was not returned from it
I really tried spending on it a few days, while googling, I tried so much ways, to mention some:
Creating a promise and resolve it in save/remove CB;
putting 'return' in so many logical combinations to make sure it
always 'return' from a promise.
Creating functions in the model, and naming it "saveAsync" (I saw it
in one example) and there doing all the promise handling.
Kinda funny but I tried updating all my project npm packages,
because I saw talks about it in github and someone mentioned they
solved it already. but it didn't work.
And much more.. I'm really desperate.
Don't get me wrong, the code works great, but seeing this HUGE warnings in my console each time makes me feel really guilty.
Any suggestions?
This error means some code did something like:
somePromise.then(x => {
someOtherPromiseReturningFunction();
}).then(value => {
// forgot a return, oh dear
});
Which is a very common mistake of forgetting a return, it messes with error handling and causes issues.
Sometimes the problem is not with your code but with the code of a library you're using - in that case you should disable warnings for that code:
Require bluebird separately for your own code and for mongoose via require("bluebird") and use it with warnings.
Disable warnings for the copy mongoose uses.
You can get two copies of bluebird by using require("bluebird") in your code and overriding mongoose's Promise with require("bluebird/js/release/promise")(); which creates a standalone copy.
Related
I'm new to Angular2 and have been charged with developing "robust error handling". So far I've followed the simplistic examples (console.logging) for adding custom error handling. But sometimes, if the page completely stops loading due to the error, we will want to redirect the user.
However sometimes, as below, although there are errors, the page otherwise loads completely. Are there are only certain types of errors that stop the page from completely loading? One of the following 6 types perhaps?
Any error can stop your page from rendering, depending on where it occurs in your process. Any error can fail to be caught if it is in a callback or other asynchronous action.
Be careful with terms like "robust error handling" - I've seen huge commercial projects that claim just that, but actually just silently truck over loads of issues, kind of like on error resume next.
I find the golden rules are:
If your app can continue through an exception (such as getting corrupt JSON data from a non-essential service) then that specific case should always be explicitly handled.
Otherwise a unexpected exception should always break something visible.
That second rule is counter intuitive, but it really is best practice. Users will complain about errors that they see, and visible exceptions and crashes will upset them and reduce their confidence in your application.
However, exceptions that they don't see still happened, and because you've silently trucked through them whatever caused them is still there. Silent exceptions cause data to be lost or corrupted. They cause the kind of bugs that you only find out about after 6 months in production. They cause the kind of bugs you can get sued over.
Users will forgive you for obvious errors that you fix quick, they will leave and never come back if you lose data and don't immediately know about it.
Ok, so that all said, the errors you seem to be highlighting are asynchronous, and related to a problem sometimes described as callback hell.
In your screenshot the error is from an HTTP GET request - this will typically be a method where you make an AJAX request, have a callback to fire when it succeeds, but don't have a callback to handle the exception.
Angular2 uses promises, which is the next error line of your screenshot. Promises wrap those callbacks and allow you to chain them - they really help with callback hell, but they're not a magic bullet: you have to make sure that every .then() has an error handler or a following .catch().
However, there is an even better way: with Angular2 you can use TypeScript, and that means you can use async and await. These are syntactic sugar for promises, but they also work with try-catch to make error handling of asynchronous exceptions much easier.
I've blogged about that in a lot more detail than I can fit here.
TL;DR: in Angular2 use async/await (with TS transpilation if you need it) to make sure that your Promise and callback exceptions make it back up, and then handle what you expect/can work around and visibly crash for what you can't.
I've been having lots of weird issues with my unit tests (see for example here or here) and I wanted to rule out this as a possibility. So, here's my potentially silly question:
Does the should style from Chai block, or is it async? Is it safe to have a done() call after some sort of should chain, or is the ideal solution callbacks of some sort?
I'm pretty sure this isn't the problem. But it seems like I discover a new problem caused by Node's non-blocking IO (or rather, my lack of experience with it) every day and I wanted to check that I wasn't making a mistake here.
I've had weird experience with .should because it needs to attach itself to object you are should-ing. I had better experience with expect(). And sync/async depends on test runner. mocha is sync. And every assertion with expect() is sequentially run, and is atomic, so there is no async operation there. Same goes for should.
i prefer expect over should because something.should will throw an error if something is undefined. no other reason for my preference.
neither should nor expect make the test async. done is what makes the test async and the done should be called in both the promise resolution and reject block (not just one). you may want to tweak the mocha (i assume mocha) timeout period before done fails. hope this helps.
I came across this answer in a SO question:
'AFAIK expect waits internally for the related promises.'
Does anyone know if this is correct? I've searched the protractor documentation for an answer with no luck. Can anyone point out the correct place in the documentation where it say this?
If it is correct, it would save me a lot of work! We have over two hundred tests, and to prevent timeouts I am converting all these types of calls:
expect(parentDialog.getAttribute('class')).toContain('k-window-maximized');
to this:
parentDialog.getAttribute('class').then(function(cls) {
expect(cls).toContain('k-window-maximized');
});
This is definitely true. expect() is "patched" by jasminewd/jasminewd2 (used by protractor internally) to implicitly resolve promises. Quote from the README:
Enhances expect so that it automatically unwraps promises before
performing the assertion.
Here is an another documentation reference:
The WebDriver Control Flow > Protractor Adaptations
In other words, unless you need a real resolved value for further actions or calculations, you can safely pass a promise into expect():
expect(parentDialog.getAttribute('class')).toContain('k-window-maximized');
Warning: I'm going to sound like I have no idea what I'm talking about here, because I kind of don't. I'm in the process of self-learning Javascript and AngularJS through a lot of trial and error coding.
I have some javascript code (hesitant to copy here because it's a mess) that returns an Object with the following structure:
What I want to save to a variable is the object corresponding to Object.$$state.value in the picture. This object has username, hash and salt, which are what I care about. I don't know what all the other stuff like $$state are or how they got there.
However, if I do this (let's call the main Object "whatIHave"):
var whatIWant = whatIHave.$$state.value;
this does not work. whatIWant is null.
Does anyone recognize what's going on here? What is $$state, how did it get there, and how can I extract the value I want?
So that is a promise. You need to do something like:
whatIHave.then(function(whatIWant) {
// Work here
});
I highly recommend you to research what a promise is (like this link)
If you're curious enough, about what is that $$state and what is that value, I will explain a bit:
The promises have a $$state and there angular saves all the callback functions you want to call in a pending array (all those function you registered with .then like I explained before).
It also have the status: resolved (1) and rejected (2)
Finally, when you resolve or reject the promise, the value you pass when doing that, is saved in value.
You're trying to cheat in here, because when you try to access that value, it could be not there yet (that is what async is all about).
So the idea is learning the basic of promises, learning how to work with them and then use your whatIHave correctly.
I'm a java developer. I really like to learn javascript. I'm finding it very difficult to pick-up a library and just learn/use it for two reasons:
1) There is no decent auto-complete. I've tried, eclipse, vjet, nodeclipse and webstorm...each has its own frustrating set of issues. Maybe the language is such that, autocomplete is super-difficult.
2) The API documentation is extremely confusing. I guess it is because I'm new to JavaScript.
For example, I wanted to figure what the callback function in mongoose.connect method does and how to declare it. So I checked the api doc. All it says is that the callback is a function...it doesn't say how many params it takes, what the values of the params are under various invocation scenarios...etc.
I feel like I'm missing something...
How does one go about reading these docs?
It's not you. I often find myself scratching my head about what the callback arguments should be. It's a problem with many JavaScript libraries.
However, in Node at least there is a convention that most libraries follow:
In node.js, it is considered standard practice to handle errors in asynchronous functions by returning them as the first argument to the current function's callback. If there is an error, the first parameter is passed an Error object with all the details. Otherwise, the first parameter is null.
For what it's worth, I haven't yet found an IDE that offers JavaScript autocomplete at anything nearly approaching the level of what's available for Java.
For the connect function, the callback passes an error argument given failure:
mongoose.connect('mongodb://localhost/dbname', function(err) {
if (err) {
// handle error
}
});
Generally, JavaScript tools are behind those for Java.
I feel like I'm missing something...
Me too. But, I think situation will change in 1-2 ears.
You can just wait for things to change or improve that you need by small step in a time.
Welcome to Nodeclipse.
It is time inefficient to solve problem only for one library (e.g. Mongoose),
but if there is web service like one for Node.js there is big chance for things change. Especially if you care enough to contribute, e.g. with ideas and materials or just raising an issue.