Recently I have been mainly working with Node JS and have been tripped up by a few things while trying to handle errors. I noticed other people were also experiencing some problems handling errors and unit testing them correctly. I thought I would make this post in case there are others out there struggling through the same.
Lesson 1: When not to use Error handling:
If a function takes a call-back as a parameter.
You cannot wrap this in a try catch and try and log out the error which is thrown within the call-back / function invocation. For example:
You cannot handle the error which is thrown within a callback by its calling function.
This is because the functionWithACallback method is called then the thread moves on. When the callback throws an error the original method has already been completed and the catch method has been processed and removed from the call stack. Because the callback is happening in parallel to the rest of this function call it will most likely complete after it.
Therefore because a call back is an asynchronous operation we cannot catch it with a try catch which assumes a synchronous operation. The code may have moved on before the callback or anything within it can throw an error.
Lesson 2: How to test throwing errors
If you are testing that a function throws an error then you must call this erroneous function within a function within the expect. For example (using chai and jest):
You cannot do this:
That is because the second will throw an error within the test so make it look to jest like the ‘it’ or ‘describe’ statement is throwing the error so it thinks that it is the test itself which is broken and throwing the error.
This is because the second will throw the error within the ‘it’ or ‘describe’ block so making it seem like it is the test throwing the error because there is something wrong with the test itself. However the first example causes the error to be thrown within the function within the expect, this is then caught by chai which then reads the ‘to.throw(error)’ and attributes this as expected behaviour.
So there you have it;
When testing don’t throw the error within the expect function but instead within a function inside the expect.