Thursday, 30 August 2018

TDD: design later

TDD is freaking awesome!

awesome GIF by Cartoon Hangover

Seriously though, for most projects, TDD is a great place to start!

Let's go on a TDD journey and see how it affects the design of a project!

leaving lets go GIF by Jim Gaffigan

So I'm working on a project, I have a reasonable idea of how I'm going to design the project and break up the abstractions. First I choose a central set of entities and begin writing tests for them.

Through doing TDD I guarantee that the project is easily testable, because I have to write tests if I choose the wrong part to test or way to test it my life is going to be painful, so I would quickly reevaluate making the wrong decisions because I'm not having TDD fun I'm having TDD pain. TDD will quickly tell you if you're doing it wrong by being extremely painful to write the tests.

As we go forward I follow my design and TDD enforces the testability of the design, and allows me to quickly refactor the design if I have miscalculated anything! Fucking A!

fun celebrate GIF by Shaun the Sheep

Another time, I'm building a new project, I have no god damn clue about how to design it. I'm not really sure how it will interact with other systems. What the API should be and really where the abstractions lie internally.

This time I just choose what seems a reasonable place to wrap the logic and begin writing tests, I write the hackiest ugliest code in a single file to satisfy the tests and focus on the quality of the tests, not the actual code. After working on the project for some time it's really going to start creaking, there are tonnes of conditional nested logic and edge cases are starting to become quite painful. But at some point, it becomes quite easy to sit down and come up with a design that actually satisfies the project.

With design in hand, I can sit down bin off the file that I was using for the main code and leverage the tests to confirm that the new design works! GLORY!


Don't agree? Leave a comment!
stephen colbert middle finger GIF


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!