In some cases I might use it as a way to intentionally throw a wrench into a machine sort of speak to stop execution of a program at a certain point as a means of debugging, but as of late I prefer to use alternatives to that to catch a state of affairs as to what is happening at a certain point in time. So for the most part the throw statement is used as a way to define my own errors, but always doing so in a way in which I am making sure that doing so is happening in the body of a try statement. Ether by using throw in a try statement, or in the body of a function that I am passing as an argument to something where try statements are being abstracted away.
- These source code examples and many more are on github
In the event that an error happens by passing any value that is not a number for one or more of the arguments, the throw statement will be reached, the user defined error will happen, and this will stop the execution of the rest of the code in the function. So the throw statement will have a similar effect to that of the return keyword in the body of a function where it will cause any additional code afterward to not run.
The value can be a string, number, boolean, or an object that should be given certain standard key value pairs, more on that later. For now you should get the basic idea at least, the throw statement will cause an error to happen, and then an additional value can be passed as a way to shed some light on what that error is.
So a string can be used to describe the user defined Error, but it might be best to use an Object or The Error constructor to create an object with message and name properties that help to better identify what is wrong when the Error is thrown. This standard object of sorts can be called you guessed it an error object that contains properties like message that is used to set the string message of the error, but also properties like name, line number, and so forth
When an Error is thrown in a try block then any catch block present with that try statement will of course be executed which can be used to handle the Error. This is something that should be used either directly, or indirectly when causing user define errors with the throw statement. That is unless for one reason or another I want the program as a whole to halt, which would end up being the case if there are no catch stamens that will prevent that from happening.
2.1 - A Basic try catch example
So for a basic try catch example with the throw keyword there is just starting with a clean try an catch block, and throwing a user define error in the try block. The catch block will then run and the value that is given when using throw will be valuable as an argument for the catch block. Although this value does not have to be an object, it is generally a good idea to stick with objects, and event going to far as to imitating certain standards with error objects such as using the Error constructor. At a minimum the object should at least have a message property.
2.2 - A Basic try catch example
In this example I am using throw in the body of a function, and then calling that function in the body of a try block. This will result in the catch block firring also.
2.3 - High order function example
So then because the throw keyword can be used in the body of a function that will trigger and catch block if the function is being called in a try block that corresponds to the catch block this opens up a lot of possibles when it comes to writing higher order functions. For example I can make some kind of high order function that works in a similar way to some of the basic features of Promises when it comes to the whole resolve and reject aspect of them.
3 - Using throw with an Error constructor
In the basic section of this post I went over an example where I am passing an object as the value to use for the throw statement. This is generally a good idea because it allows for me to attach additional useful information with it comes to handing an error when it happens.
3.1 - The basic Generic Error object constructor
So when it comes to the generic Error constructor the constructor can be called with or without the new keyword actually. Many code examples will involve the use of the new keyword when using it, but the same result is achieved with or without the use of it. When calling it the first argument given should be the message for the Error.
This might be a good starting place when it comes to using an Error constructor, however the name of the Error object that is just simply Error is not always so helper when it comes to classifying the different types of errors that can happen in a program.
3.2 - RangeError constructor
There is a built in RangeError constructor which can be used to define a typically type of error thats has to do with a given value being outside of an expected range.
4 - Using promises and the throw keyword
When using a Promise there is calling the resolve or reject methods in the body of a function that I pass to the Promise constructor that I call with the new keyword. When I call the reject method I pass an Error object that will be accessible as an argument for the next catch function call in the returned promise object. However another way to get the next catch block to call is by just throwing any kind of exception in the body of the function, this two will seem to work fine and cause the next catch function call to fire that can then be used as a way to handle the error.
4.1 - Basic promise example
So when I write a promise I often call the reject method inside the body of the function that I give to the constructor. When I d so I typically pass an Error object that will be the nature of the reason as to why the promise is to be rejected. However I can also just use the throw keyword in the body of the function without calling anything that will also serve as a way to trigger the next catch call in the promise chain.
5 - Global Error handers and throw
5.1 - In nodejs the default of what happens when using throw in
By default when making a nodejs script if I use the throw keyword in the top level any code after that will not file at all. On top of that the default action of nodejs for this kind of error is to print what happened to the standard error, and then call the process.exit method with a status code of 1.
So what if I want something else to happen in this kind of situation? Such as setting the exit code to some other kind of code other than 1, of maybe even not call process.exit at all actually? With that said at least a one if not more examples are called for when it comes to this sort of thing then.
5.2 - Using an event hander in which I DO NOT call process.exit
In nodejs I can use the on method of the process object to attach an event handler for the uncaughtException event. When doing so I will want to make sure that I attach the event first before any kind of situation happens involving throw that might not be handled. Inside the body of the handler I can do something other than one the default is for an manhandled error, such as printing to the standard output rather than standard error, an choosing to not call the process.exit method at all actually.
Choosing not to call process.exit at all is what I have decided to do here, as a result the console.log at the bottom of the script will still not fire because of the throw statement. However the loop continues until the count of zero is reached, at which point the script then exits.
6 - Conclusion