Sunday, 19 August 2018

using errors

Much error handling has to be tailored to the situation that suits it, at a minimum, you will want an overall error handler for an API call to handle unexpected errors and report them to the consumer and probably a log.

sometimes we can do something when an error occurs before it hits the default handler, in this case, we return cached data instead.

One important thing to note is the extra value that is added when using the Error class even when rejecting a promise.

This will mean that when we log out the error in the error handler we also get a stack trace, as when a new error is created it records the current stack.

In some cases, we may not be able to fix the problem but we may be able to add additional information to help us when reading the logs later.

now the log will contain the user id and save us some time when debugging later!

Some error cases may be something that we cannot do anything about but the user can, in this case, we are going to need to tell them about it, this hopefully saves us being contacted by the consumer/user and they can fix their own problem.

In this case, we create an additional error type that extends error so that we can bubble that up to be able to alert the user that their account is disabled.

Saturday, 18 August 2018

express error handling

Here are a few ideas for error handling in an express app.

For all cases, you will want every route to handle any errors that can occur so that we can notify the caller and potentially do some logging.

Now, this can become quite tedious and repeated so we can pass the error to expresses default error handler!

This will cause express to pass the error out to the client, which in most cases is probably not what we want, so let's have a look at replacing the default error handling middleware.

This now gives us control to be able to add some default logging and return the status we want as well as and information we want to show to the consumer.

One really important thing to remember is to put the function after you define your route handlers! Or it won't catch the errors. (at the bottom of the file)

There are a few different types of things you might be doing in the routes so here are a few examples of how to pass the errors.

This one just handles synchronous code that throws errors.

In this case, we see an example of how to pass callback based errors.

And then moving into promises, as long as we make sure that we pass the error to next, the error handler middleware will be activated.

More on error handling strategies to come!

project coding GIF

Friday, 10 August 2018

async/await in node.js: error handling

So, let's have a quick look at async await error handling!

Like last time we are wrapping our code in a self-executing function so we can use the async keywords.

To handle errors in async functions we use a try-catch block like we normally would in synchronous code. You can see from the example that a rejected promise comes out of our catch block.

As we know from previous posts a promise will be rejected if reject() is called or an error is thrown inside of the promise.

Also if you throw an error in an async function this results in a rejected promise. So you can see now how it all fits together, any promise rejections or errors thrown result in the catch block being used.

Just worthy to note that non-awaited rejected promises will not trigger the catch block but will put up an unhandled promise rejection error.

Thursday, 9 August 2018

async/await in node.js

Async await is a syntax that makes your asynchronous code look more like synchronous code, it is basically some nice syntactic sugar built on top of Promises.

You just add the async keyword to your function and or expression and that method will now return a promise! You can then use the await keyword to get the result of the promise!

One thing to note is await can only be used inside of an async function, so if you want to execute the code just in a file you need to wrap it in a self-executing function.

I know what you're thinking, "This is great so I can stop writing those weird promises now right?", well no. Though you can quickly create synchronous-looking code that returns promises in either resolved or rejected state.

This does not allow for the handling of asynchronous code that is not promise based inside of your function.

Unfortunately, this will not work as the function will just return a promise that has undefined or no value. To get around this we need to wrap our callback code in a promise as before.

This can now be used in an async function!

You can also make good use of util.promisify to help you with this!

Just remember it will only work for functions where the parameters match the node pattern of callback last and the callback starts with the error.

You can see in this case that by defining our callback method to the node standard util.promisify happily wraps it in a promise.

In this case, I removed the parameter passed to doTest() this results in a "TypeError: callback is not a function" error being thrown, which will be very confusing if you didn't write the callback code you are wrapping and it doesn't have very good error messages.

More on async/await soon!

Wednesday, 8 August 2018

Promises in node.js: nesting promise patterns

Join me for a little exploration in some patterns that can be used with promises, we will mainly play around with different ways to pass data through promise chains and how to get what you want out of the other end.

Here we are loading the user information, then passing the id from that object to another two promises. The reason the two on the inside are nested is that they both need access to the user object. This also leads to another potential problem because the inner promises are executed sequentially, and in our case, they don't need to be.

This solves the problem in a pretty neat way, we wrap the two inner calls together in a Promise.all() to get them to execute in parallel. Notice how we take advantage of array destructuring to pass in the results together, this is a very useful little pattern.

There may be a specific requirement for this to be changed into an object rather than an unwrapped array, in this case maybe you could wrap both calls in a method with a .then() map.

It's up to you really where the different conversions and abstractions go, I'd advise being careful of having lots of little functions to wrap things up as it leads to code being hard to follow.

But what if we want to merge all of the data together into a single object, you can, of course, do this by nesting all the promises into one inner promise to share the data, but what if we are trying to avoid doing that?

In this case, we change all of the functions to take and return a context object that is updated by each function, this can seem a desirable way to do things but I would recommend against it. Firstly now every method isn't really a pure loading method its kind of a loadUserMessagesAndUpdateContext() method, while if you use this pattern lots I'm sure people wouldn't be too confused unless they hit issues with the way this is going to execute. If you look at my examples they will update the context object before they resolve. Most of the time this probably won't be a problem, but it could definatly give someone a headache.

Join me next time when we look at async/await!

Tuesday, 7 August 2018

Promises in node.js: Helper functions

Today we will have a look at some of the cool helper methods provided by the native promise framework. The first couple are just quick helpers to create promises in different states.

These methods quickly wrap values in promises of either resolved or rejected state. This will then execute the path that that promise would normally go down (i.e. .then() for resolved, .catch() for rejected).

In this example we use a made up httpGet function and pass in urls to get an array of returned data. The simplest way to think about Promise.all is that it takes an array of promises and returns a single promse that resolves when all of the promises in the array are complete.

This helper is similar to all except as the name suggests it just returns the first one that completes, this could potentially be a way of implementing timeouts on things, I find myself using Promise.all() much more frequently, but still it is good to understand!

Finally blocks are useful to help you close down resources no matter what happens.

Just a quick note to show that promises can have .then() put on them after they complete and the chain will still be executed. The reason for attaching this inside of another .then() was so that the eventloop would get a chance to fire before attaching the new one.

More promises coming soon!

Monday, 6 August 2018

Promises in node.js: Error Handling

Continuing on with the promise theme, let's have a look at error handling.

When executing this you will get a warning, that starts with:
UnhandledPromiseRejectionWarning: This is a rejected Promise
The warning also tells you that the error was not handled by a .catch() block.

In this case we get a similar message: UnhandledPromiseRejectionWarning: Error: An error happened inside the promise, but not rejected.
Both cases can be handled by adding a catch block to the code.

To add an error handler we just add a .catch() block to the end of the promise execution chain, if reject is called then the parameters passed to reject will come out of the catch handler function.
If an error is thrown then the error will come out of the handler function. So we can see how .catch() blocks are very useful but you need to be careful about nesting promises inside of each other.

In this case, we get an unhandled promise rejection message again, because the .catch() block will not pick up the rejected promise. To solve this we can do a couple of things, in most cases, you can just bubble the promise out of the inner .then() block.

The error handling will now work at a higher level because the promise chains are connected. But sometimes we may want to do some additional handling first.

It is still important to connect the chains by returning the inner promise chain or the outer handler won't fire. When a promise is returned from inside a then block the new promise state will be dependent on the inner one.

In this case, the inner error block will fire but not the outer, as no error was thrown. And the outer .then() block will still fire!

So if you do want to execute both catch blocks make sure to throw an error in the inner one, how much of a good practice this is I'm not sure but it helps to understand what state the promises are in.