How to promisify correctly JSON.parse method with bluebird - javascript

I'm trying to promisify JSON.parse method but unfortunately without any luck. This is my attempt:
Promise.promisify(JSON.parse, JSON)(data).then((result: any) => {...
but I get the following error
Unhandled rejection Error: object

Promise.promisify is thought for asynchronous functions that take a callback function. JSON.parse is no such function, so you cannot use promisify here.
If you want to create a promise-returning function from a function that might throw synchronously, Promise.method is the way to go:
var parseAsync = Promise.method(JSON.parse);
…
parseAsync(data).then(…);
Alternatively, you will just want to use Promise.resolve to start your chain:
Promise.resolve(data).then(JSON.parse).then(…);

Late to the party, but I can totally understand why you might want a promisified JSON parse method which never throws exceptions. If for nothing else, then to remove boilerplate try/catch-handling from your code. Also, I see no reason why synchronous behavior shouldn't be wrapped in promises. So here:
function promisedParseJSON(json) {
return new Promise((resolve, reject) => {
try {
resolve(JSON.parse(json))
} catch (e) {
reject(e)
}
})
}
Usage, e.g:
fetch('/my-json-doc-as-string')
.then(promisedParseJSON)
.then(carryOn)
.catch(dealWithIt)

First of all, JSON.parse is not an asynchronous function. So, don't try to promisify it.
Because I want to create a chain of promises where JSON.parse stand at the top
Then, simply create a Promise resolved with the parsed JSON object, like this
Promise.resolve(JSON.parse(data))
.then(...)
Now, to your actual question, you are getting the error,
Unhandled rejection Error: object
because, if your chain of promises is rejected, you are not handling it. So, don't forget to attach a catch handler, like this
Promise.resolve(JSON.parse(data))
.then(...)
.catch(...)
READ THIS There is a problem with the approach I have shown here, as pointed out by Bergi, in the comments. If the JSON.parse call fails, then the error will be thrown synchronously and you may have to write try...catch around the Promise code. Instead, one would write it as Bergi suggested in his answer, to create a Promise object with just the data, and then do JSON.parse on that Promise chain.

Related

How to handle error and use promises correctly

To begin with, I am taking a follow up from this question I posted few moments ago
Now, I thought I knew Aysnc and Promise but clearly I am missing something.
Referencing to the Tagged answer by estus,
Unless API supports promises, errors should be entirely handled in
async function. Function body should be wrapped with try..catch to
rule out unhandled rejections which may result in exceptions in future
Node versions
From which I was able to comprehend that whenever we are using aysnc function and we want to do error Handling we need to use try..catch and for normal Promises we could simple do resolve/reject or if it is already a promise then we can chain and do .then and .catch but for that I got following reply on comment
Yes, you can expect an error. async/await is just syntactic sugar for
raw promises. Any async function can be rewritten in plain ES6
I might be keeping this question broad but can someone please help me in explaining..
When do we need to use
.then and .catch
and when do we need to use
try..catch
Also, What does it mean by
Unless API supports promises
Async await code looks cleaner and easy to read. The Promises were created to solve the callback hell problem but chaining a lot of promises also confusing. So async wait is a syntactical sugar and you can use any one of the .then or async await.
If you are using simple promises syntax then you can use .then.then.then.catch() syntax.
if you are using async and await then you have to use try catch. All the await will go in try and the catch condition would go in single catch.
Both these can be used when API/function you are using returns a promise.
try...catch in async function is syntactic sugar for catch() in raw promise. If raw promises are used for some reason (legacy code) then catch() may be used. This shouldn't be a problem in Node, since recent versions support async..await.
Notice that try..catch catches both synchronous and asynchronous errors in async. This should be taken into account to not leave synchronous errors unhandled with plain promise.
If API doesn't support promises, you cannot expect that promise rejection that is returned from a function be handled by API, so you need to do this yourself.
// So this is how promises work (as you may already be familiar with)
function promiseFu() {
return new Promise((resolve, reject) => {
reject();
})
.catch(e => {
// The exception has been handled
console.error("Error begin in promiseFu()!")
throw e; // <- now this triggers the second exception
})
}
// Asynchronous functions are the functions that ALWAYS returns a promise
// therefore, this is also correct
async function asyncFu() {
return new Promise((resolve, reject) => {
reject();
})
.catch(e => {
// The exception has been handled
console.error("Error begin in promiseFu()!")
throw e; // <- now this triggers the second exception
})
.catch(e => {
// Here the second exception gets handled as well, and asyncFu does not throw any exception in the end
})
}
// Now the power of async await
async function asyncMainFu() {
// using await before an async function would make it wait for the function to complete asynchronously before moving on
await asyncFu()
// await would do the same with promises as well
// await promiseFu() // <- this is correct as well
// BUT now, if you see promiseFu() is throwing the second exception which is not yet handled,
// asyncMainFu() would throw the same exception as well. unless handled by a try..catch block
try {
await promiseFu()
} catch(e) {
// handling the exception thrown by promiseFu and not throwing any new exception
// is a good idea if you think caller of asyncMainFu() might not handle it.
}
}

Code works, but is it best practice to have a try/catch block inside a promise?

Is it good practice to wrap a try/catch with a Promise? I was reviewing the code below, I cannot seem to understand the necessity of having a try/catch block inside a Promise. Also, why would there be no place where the Promise rejects, as you can see in the catch block, the Promise resolves. Please help me understand this piece of code, in terms of best practice and efficiency the point of having the try/catch inside the Promise.
I would also really appreciate any suggestions regarding cleaning the code up where it is redundant.
getRoute(): any {
return async (request: any, reply: any) => {
const result = new Promise<string>( async (resolve, reject) => {
try {
let userIsValid = await this.validator.validate(request.payload, RegisterUserValidator);
if (userIsValid.error) {
resolve(responseHelper.getErrorResponse(ResponseErrorCode.joiValidatorError, userIsValid.error));
throw new ControlFlowNonError();
}
let results = await this.authUser.registerUser(request.payload);
resolve(responseHelper.getSuccessResponse(results, null));
}
catch (error) {
let message: ILogMessage = {
code: ResponseErrorCode.unknownError,
message: ResponseErrorCode.unknownError.toString(),
meta: error,
sourceFunction : 'ApiDataCreateCredentials: getRoute()'
};
this.logHelper.error(message);
resolve(error);
}
});
reply(result);
};
};
Is it best practice to have a try/catch block inside a promise [executor function]?
No, it's not best practice. There's pretty much no reason to use promises inside a promise executor function. Because when you're doing that, you don't need the outer, manually created promise at all. You can just return the inner promise. That's the Promise constructor anti-pattern.
FYI, though it isn't your case here, it is reasonable to use try/catch to handle regular exceptions inside a promise executor (if the manually created promise executor is actually needed in the first place and if regular exceptions are of concern and you want to handle them locally).
Here's another idea for how to accomplish your same logic. This removes the promise anti-pattern of surrounding a promise with another manually created one and uses promise flow control to make userIsValid.error go to the log error code. I didn't see any particular advantage of using await here so I switched back to just using .then() and .catch(). I don't know TypeScript so this is a regular Javascript version of the code, but you can presumably add the slight syntax differences yourself to turn it back to TypeScript:
getRoute(): function() {
return function(request, reply) {
return this.validator.validate(request.payload, RegisterUserValidator).then(userIsValid => {
if (userIsValid.error) {
// treat this as an error condition
throw responseHelper.getErrorResponse(ResponseErrorCode.joiValidatorError, userIsValid.error);
}
return this.authUser.registerUser(request.payload).then(results => responseHelper.getSuccessResponse(results, null));
}).catch(error => {
let message: ILogMessage = {
code: ResponseErrorCode.unknownError,
message: ResponseErrorCode.unknownError.toString(),
meta: error,
sourceFunction : 'ApiDataCreateCredentials: getRoute()'
};
this.logHelper.error(message);
// turn back into resolved promise with error as the result
return error;
}).then(reply); // always call reply
}
}
Things that did not seem ideal with your implementation:
Promise anti-pattern (creating an unnecessary wrapper promise).
Calling resolve() multiple times (the second one will be ignored, but it seems less than ideal to code it that way)
There does not seem to be any particular benefit to using async/await here. It seems to complicate the flow (in my opinion).
resolve() followed by throw is a real head scratcher when reading the code. Yes, one can eventually figure out what you're trying to do, but this is an odd way to do it. My scheme is a bit more semantic. if (userIsValid.error) is really just an error condition for you so coding it this way just makes that more obvious. Then, since you want ALL errors to proceed as if there was no error (after logging), we just make the .catch() handler return normally which allows the last .then() handler to always get called.
Other references related to your topic:
Can't throw error from within an async promise executor function
Is it an anti-pattern to use async/await inside of a new Promise() constructor?

Should simple statement be surrounded by Promise.try in bluebird promises?

Using promisified request module, i want to get the body attribute of the response. Not sure if I should use a Promise try.
So which one is correct here ?
A. Without Promise.try
request.getAsync("http://example.com")
.then( x => x.body )
.tap( x=> console.log('body:',x) )
B. With Promise.try
request.getAsync("http://example.com")
.then( x => Promise.try( () => x.body ) )
.tap( x=> console.log('body:',x) )
After the first element of a promise chain, an error is guaranteed to throw down the chain's error path and become available to be caught by a .then(null, errorHandler) or .catch(errorHandler).
Therefore there is no point using Bluebird's Promise.try() other than to get a chain reliably started. Doing so will just bulk up your code and make it less efficient.
How about inner chains?
This is more interesting. Inner chains are commonly used to allow access to earlier results via closure. Flattened chains lose this ability.
Consider :
request.getAsync("http://example.com")
.then( x => {
return untrusted.method().then((y) => other.method(x, y));
});
The inner chain has its own starter, untrusted.method(), which may cause failure in one of two ways:
it may throw.
it may return a non-thenable.
A throw is unavoidable (without addressing untrusted.method()), though the thrown error will be catchable in the outer chain.
But a non-thenable can be guarded against. You can write :
request.getAsync("http://example.com")
.then(x => {
return Promise.try(untrusted.method).then((y) => other.method(x, y) );
});
Now Promise.try() ensures the inner chain has a reliable start. Promise.try(untrusted.method) is guaranteed to be thenable.
As a bonus, an error thrown by untrusted.method() is now catchable in the outer chain or the inner chain, which can be useful, particularly for error recovery.
Promise.resolve(untrusted.method()) would similarly protect against a non-thenable being returned but would not allow a synchronous throw to be caught within the inner chain.
DEMO: untrusted() throws
DEMO: untrusted() returns value, not promise.
So in summary,
within a promise chain, there's no value in wrapping synchronous expression(s) in Promise.try().
within a promise chain , there's no value in wrapping trusted, asynchronous function/method calls in Promise.try().
within a promise chain, there is potentially great value in wrapping an untrusted function/method call in Promise.try() to guarantee an inner chain's reliable start.
Not sure if I should use a Promise.try.
No, you should not. In a promise then callback, all synchronous exceptions will be caught and lead to a rejection of the result promise, there is nothing you need to do for that. No try/catch statements, no Promise.try invocations. They would just be unnecessary fluff.
Promise.try should only be used at the start of a promise chain, where you are not yet in a promise callback.
The definition of this Promise.try is:
Start the chain of promises with Promise.try. Any synchronous
exceptions will be turned into rejections on the returned promise.
So it depends by the implementation of request.getAsync method. Does it throw any exception?
If the answer is "no", you do not need to use Promise.try.
If the answer is "yes", you can use Promise.try if you need to catch the error thrown by request.getAsync as rejected promise. In this case, you can wrap the
request.getAsync inside Promise.try:
Promise.try(() => {
return request.getAsync("http://example.com");
}).tap(x => console.log('body:', x.nody));
Please note that if the answer is "yes" but do not want to catch the exception as a rejected promise, you do not need to use Promise.try.

Catching Errors from Promise construction

Is there a better way of doing the following using Bluebird promises
Promise.resolve()
.then(function() {return new MyObject(data)})
.then.....etc
.catch(function (e){ //handle it})
I have MyObject - and data passed in from an external system, which could be invalid, thus could break the promise chain. Wrapping the object creation in a function in a then seems really messy tho. Is there something like
Promise.something(new MyObject(data))
.then()....
.catch....
Also - Node 0.10 so no Lambda to make it look tidier :-(
Rather than Promise.something(new MyObject(data)), which runs new MyObject before creating the Promise, use the long-form promise constructor:
new Promise(function (resolve) {
resolve(new MyObject(data));
}.then(foo).catch(bar);
Exceptions thrown synchronously within a promise constructor or then callback will be caught, processed (including type matching), and sent on to catch handlers (Bluebird docs).
Sure there is, Promise.try, also you should be using arrows for short function expressions in Node:
Promise.try(() => new MyObject(data));
Like in browsers, you can use a transpiler for old versions of Node.
Also, I would not perform IO in a constructor but that's another story. The other answer by ssube explains why a constructor is needed because exceptions occur before the method is actually called.

Understanding promises in Node.js

From what I have understood there are three ways of calling asynchronous code:
Events, e.g. request.on("event", callback);
Callbacks, e.g. fs.open(path, flags, mode, callback);
Promises
I found the node-promise library but I don’t get it.
Could someone explain what promises are all about and why I should use it?
Also, why was it removed from Node.js?
Since this question still has many views (like mine) I wanted to point out that:
node-promise looks rather dead to me (last commit was about 1 year ago) and contains nearly no tests.
The futures module looks very bloated to me and is badly documented (and I think that the naming conventions are just bad)
The best way to go seems to be the q framework, which is both active and well-documented.
Promises in node.js promised to do some work and then had separate callbacks that would be executed for success and failure as well as handling timeouts. Another way to think of promises in node.js was that they were emitters that could emit only two events: success and error.
The cool thing about promises is you can combine them into dependency chains (do Promise C only when Promise A and Promise B complete).
By removing them from the core node.js, it created possibility of building up modules with different implementations of promises that can sit on top of the core. Some of these are node-promise and futures.
A promise is a "thing" which represents the "eventual" results of an operation so to speak. The point to note here is that, it abstracts away the details of when something happens and allows you to focus on what should happen after that something happens. This will result in clean, maintainable code where instead of having a callback inside a callback inside a callback, your code will look somewhat like:
var request = new Promise(function(resolve, reject) {
//do an ajax call here. or a database request or whatever.
//depending on its results, either call resolve(value) or reject(error)
//where value is the thing which the operation's successful execution returns and
//error is the thing which the operation's failure returns.
});
request.then(function successHandler(result) {
//do something with the result
}, function failureHandler(error) {
//handle
});
The promises' spec states that a promise's
then
method should return a new promise that is fulfilled when the given successHandler or the failureHandler callback is finished. This means that you can chain together promises when you have a set of asynchronous tasks that need to be performed and be assured that the sequencing of operations is guaranteed just as if you had used callbacks. So instead of passing a callback inside a callback inside a callback, the code with chained promises looks like:
var doStuff = firstAsyncFunction(url) {
return new Promise(function(resolve, reject) {
$.ajax({
url: url,
success: function(data) {
resolve(data);
},
error: function(err) {
reject(err);
}
});
};
doStuff
.then(secondAsyncFunction) //returns a promise
.then(thirdAsyncFunction); //returns a promise
To know more about promises and why they are super cool, checkout Domenic's blog : http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/
This new tutorial on Promises from the author of PouchDB is probably the best I've seen anywhere. It wisely covers the classic rookie mistakes showing you correct usage patterns and even a few anti-patterns that are still commonly used - even in other tutorials!!
http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
Enjoy!
PS I didn't answer some other parts of this question as they've been well covered by others.
Mike Taulty has a series of videos, each of them less than ten minutes long, describing how the WinJS Promise library works.
These videos are quite informative, and Mike manages to show the power of the Promise API with a few well-chosen code examples.
var twitterUrl = "http://search.twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });
promise = promise.then(
function (xhr) {
},
function (xhr) {
// handle error
});
The treatment of how exceptions are dealt with is particularly good.
In spite of the WinJs references, this is a general interest video series, because the Promise API is broadly similar across its many implementations.
RSVP is a lightweight Promise implementation that passes the Promise/A+ test suite. I quite like the API, because it is similar in style to the WinJS interface.
Update Apr-2014
Incidentally, the WinJS library is now open source.
Another advantage of promises is that error handling and exception throwing and catching is much better than trying to handle that with callbacks.
The bluebird library implements promises and gives you great long stack traces, is very fast, and warns about uncaught errors. It also is faster and uses less memory than the other promise libraries, according to http://bluebirdjs.com/docs/benchmarks.html
What exactly is a Promise ?
A promise is simply an object which represents the result of an async operation. A promise can be in any of the following 3 states :
pending :: This is the initial state, means the promise is neither fulfilled nor rejected.
fulfilled :: This means the promise has been fulfilled, means the value represented by promise is ready to be used.
rejected :: This means the operations failed and hence can't fulfill the promise.
Apart from the states, there are three important entities associated to promises which we really need to understand
executor function :: executor function defines the async operation which needs to be performed and whose result is represented by the promise. It starts execution as soon as the promise object is initialized.
resolve :: resolve is a parameters passed to the executor function , and in case the executor runs successfully then this resolve is called passing the result.
reject :: reject is another parameter passed to the executor function , and it is used when the executor function fails. The failure reason can be passed to the reject.
So whenever we create a promise object, we've to provide Executor, Resolve and Reject.
Reference :: Promises
I've been also looking into promises in node.js recently. To date the when.js seems to be the way to go due to its speed and resource use, but the documentation on q.js gave me a lot better understanding. So use when.js but the q.js docs to understand the subject.
From the q.js readme on github:
If a function cannot return a value or throw an exception without
blocking, it can return a promise instead. A promise is an object that
represents the return value or the thrown exception that the function
may eventually provide. A promise can also be used as a proxy for a
remote object to overcome latency.
Promise object represents the completion or failure of an asynchronous operation.
So in order to implement a promise, you need two parts:-
1.Creating Promise:
The promise constructor accepts a function called an executor that has
2 parameters resolve and reject.
function example(){
return new Promise (function(resolve , reject){ //return promise object
if(success){
resolve('success'); //onFullfiled
}else{
reject('error'); //onRejected
}
})
}
2.Handling Promise:
Promise object has 3 methods to handle promise objects:-
1.Promise.prototype.catch(onRejected)
2.Promise.prototype.then(onFullfiled)
3.Promise.prototype.finally(onFullfiled,onRejected)
example.then((data) =>{
//handles resolved data
console.log(data); //prints success
}).catch((err) => {
//handles rejected error
console.log(err); //prints error
})

Categories