Welcome to our free Advanced JavaScript Programming tutorial. This tutorial is based on Webucator's Advanced JavaScript Programming course.
Web browsers are such a hostile environment that it is almost guaranteed that we will constantly deal with runtime errors. Users provide invalid input in ways you didn't think of. New browser versions change their behavior. Ajax calls can fail for any number of reasons.
Many times we cannot prevent runtime errors from happening, but at least we can deal with them in a manner that makes the user experience less traumatic.
Look at this seemingly trivial code sample:
---- C O D E O M I T T E D ---- function getInput() { var name = prompt('Type your name', ''); alert('Your name has ' + name.length + ' letters.'); } getInput(); ---- C O D E O M I T T E D ----
It may not be obvious, but this code has a bug waiting to break free. If the user clicks Cancel or presses Esc the prompt()
function will return null
, which will cause the next line to fail with a null reference error.
If you as a programmer don't take any step to deal with this error, it will simply be delivered directly to the end user, in the form of a utterly useless browser error message like the one below:
Depending on the user's browser or settings, the error message may be suppressed and only an inconspicuous icon shows up in the status bar. This can be worse than the error message, leaving users thinking the application is unresponsive.
The window
object has an event called error
for which we can add an event handler, listening for global errors. The next demo shows an example of this:
---- C O D E O M I T T E D ---- window.addEventListener("error", function (e) { alert('Error: ' + e.error.message); return true; }); function getInput() { var name = prompt('Type your name', ''); alert('Your name has ' + name.length + ' letters.'); } getInput(); ---- C O D E O M I T T E D ----
If the user presses the "escape" key when the prompt asks for a name, our event handler fires.
Here's the alert that we shows to the user:
The best way to deal with errors is to detect them as close as possible to where they occur. This will increase the chance that we know what to do with the error. To that effect JavaScript implements structured error handling, via the try...catch...finally
block, also present in many other languages:
try { statements; } catch (error) { statements; } finally { statements; }
The idea is simple. If anything goes wrong in the statements that are inside the try
block's statements then the statements in the catch
block will be executed and the error will be passed in the error
variable. The finally
block is optional and, if present, is always executed last, whether or not an error is caught.
Let's fix our example to catch that error:
---- C O D E O M I T T E D ---- window.addEventListener("error", function (e) { alert('Error: ' + e.error.message); return true; }); function getInput() { try { var name = window.prompt('Type your name', ''); alert('Your name has ' + name.length + ' letters.'); } catch (error) { alert('The error was: ' + error.name + '\n The error message was: ' + error.message); } finally { //do cleanup } } getInput(); ---- C O D E O M I T T E D ----
The error
object has two important properties: name
and message
. The message
property contains the same error message that we have seen before. The name
property contains the kind of error that happened and we can use that to decide if we know what to do with that error.
With that in place, if we reload the page and cancel out of the prompt, we will get the following alert:
It's a good programming practice to only handle the error on the spot if you are certain of what it is and if you actually have a way to take care of it (other than just suppressing it altogether.) To better target our error handling code, we will change it to only handle errors named "TypeError", which is the error name that we have identified for this bug.
---- C O D E O M I T T E D ---- window.addEventListener("error", function (e) { alert('Error: ' + e.error.message); return true; }); function getInput() { try { var name = window.prompt('Type your name', ''); alert('Your name has ' + name.length + ' letters.'); } catch (error) { if (error.name == 'TypeError') { alert('Please try again.'); getInput(); } else { throw error; } } finally { //do cleanup } } getInput(); ---- C O D E O M I T T E D ----
Now if a different error happens, which is admittedly unlikely in this simple example, that error will not be handled. The throw
statement will forward the error as if we never had this try...catch...finally
block. It is said that the error will bubble up.
We can use the throw
statement to throw our own types of errors. The only recommendation is that our error object also has a name
and message
properties to be consistent with the built-in error handling.
throw { name: 'InvalidColorError', message: 'The given color is not a valid color value.' };
This tutorial is based on Webucator's Advanced JavaScript Programming Course. We also offer many other JavaScript Training courses. Sign up today to get help from a live instructor.