© Russ Ferguson and Keith Cirkel 2017
Russ Ferguson and Keith CirkelJavaScript Recipes10.1007/978-1-4302-6107-0_19

19. Debugging and Handling Exceptions

Russ Ferguson and Keith Cirkel2
(1)
Ocean, New Jersey, USA
(2)
London, UK
 

What Is an Error in JavaScript?

Problem

How do errors occur and can you create an error object?

Solution

Errors result when there is a problem with code execution in the runtime . When this happens, the runtime will generate an Error object with information about what just happened. There are instances where developers can create user-defined errors that can be useful when debugging.

The Code

new Array(-1) //returns Uncaught RangeError: Invalid array length
//user defined error
console.log(new Error('this is a problem')); //returns Error: this is a problem(...)
Listing 19-1.
Two Types of Errors, One During Runtime, the Other User-Defined

How It Works

Errors usually happen when the runtime is faced with something unexpected. In Listing 19-1, trying to create an array with a new constructor and a negative number will result in an error.
The second example is a user-defined error object. You can define the error message as part of the object.

What Are the Different Types of Errors?

Problem

You want to know how many types of errors exist in JavaScript.

Solution

There are a few types of error objects that JavaScript generates. The runtime will throw them depending on the code being executed.

The Code

var evalMsg = new EvalError('This is an eval error');
console.log(evalMsg.message); //returns This is an eval error
new Array(-1);  //returns RangeError: Invalid array length
32.3333.toExponential(-1) //returns RangeError
434.2322.toFixed(-100) //return RangeError
var rangeMsg = new RangeError('This is a Range error');
console.log(rangeMsg.message); //returns This is a Range error
console.log(myVar); //returns Uncaught ReferenceError: myVar is not defined
window.alert( //return Uncaught SyntaxError: Unexpected end of input
var myObj = new Object();
console.log(myObj.causeError()) //returns Uncaught TypeError: myObj.causeError is not a function
decodeURIComponent('a%AFc'); //returns Uncaught URIError: URI malformed
Listing 19-2.
Different Types of Errors that Can Happen in JavaScript

How It Works

EvalError: This is the result of an error with the eval() function. JavaScript does not throw this error anymore, but it retains it for compatibility.
RangeError: This object is the result of a value not in the range of allowed values.
ReferenceError: Happens when you try to use something like a variable that has not been defined yet.
SyntaxError: Sometimes called parsing errors, these happen when the runtime cannot parse the code.
TypeError: Happens when trying to access a method or property of an object that does not exist.
URIError: This error is thrown when the URI a function is using is malformed.

How Can Try/Catch/Finally Be Used for Debugging?

Problem

You want to know how a try/catch statement can be used for debugging.

Solution

Try/catch statements can execute code. If an error occurs, the code can catch the error and fix any problems.

The Code

function checkStarShip(shipName){
         try{
                if(shipName !== 'Enterprise'){
                        throw new Error('Wrong Ship');
                }
         }catch(e){
                console.log(e);
                console.log('Looking for Enterprise');
         }finally{
                console.log('Continue working with code');
         }
}
checkStarShip('TARDIS');
//returns
//Error: Wrong Ship
//Looking for Enterprise
//Continue working with code
Listing 19-3.
An Example of a Try/Catch/Finally Block

How It Works

Try/Catch statements give developers a chance to recover if an error is thrown. You can also check if the error is of a certain type by using the instanceof keyword.
The try block contains a statement where you believe the code may throw an exception. Curly braces ({}) are required if a single statement is made. After the try block you can have a combination of either the catch block, the finally block, or both.
The catch block will give the developer the opportunity to handle when an exception has been thrown in the try block. The purpose is to try to fix any errors that happen within the try block. If no errors are thrown, then the catch block is ignored.
The finally block executes after the try and catch blocks . The finally block always executes even if no exception is thrown.

How Does Throw Work in a Try/Catch and Can You Rethrow?

Problem

The throw statement is used often with a try/catch, so you wonder how it can help debug the app.

Solution

If you have functions that call functions (what is called a call stack ), the throw statement can return errors to the previous catch block in the call stack.

The Code

function level1(){
         try{
                  level2();
         }catch(e){
                  console.log('Error in Level 1: ' + e.message); //returns Error in Level 1: Error started in Level 3
                  console.log(e.stack);  // returns Error: Error started in Level 3
                                                                    // also shows all the stack information
         }
}
function level2(){
         try{
                  level3();
         }catch(e){
                  console.log('Error in Level 2: ' + e.message); //returns Error in Level 2: Error started in Level 3
                  throw(e)
         }
}
function level3(){
         throw(new Error('Error started in Level 3'));
}
level1();
Listing 19-4.
The Throw Statement Returns an Error to the Previous Catch Statement

How It Works

The throw statement will stop execution of all code that is after it when a user-defined exception is found. It will pass the exception to the first catch block on the call stack.
In this example, we do what is called a rethrow . Even though the word itself is not part of the JavaScript language, the principle is the same. As functions call other functions, generating what is known as the call stack, exceptions are checked for using the try block.
When you’re finding an error, preserving the stack trace information becomes important. This is what tells you where the problem lies. The throw statement gives you a bubble-like effect (see Chapter 18 about events and bubbling), where the error goes back up the stack trace.
When reaching the top of the stack, not only will the error be displayed in the console, but the stack property of the error object retains where the error originated from.

What Is the Callback Pattern?

Problem

You want to know what a callback pattern is and how you can use it to find errors.

Solution

Callbacks are used often in JavaScript. Functions are passed as properties of other functions. You can execute a particular function in case of error.

The Code

function onSuccess(){
         console.log('You are Correct');
}
function onError(e){
         console.log(e.message);
}
function isFirstOfficer(name, onError, onSuccess){
         if(name === 'Spock'){
                  onSuccess();
         }else{
                  onError(new Error('Sorry, Wrong Officer'));
         }
}
isFirstOfficer('Scotty', onError, onSuccess);
isFirstOfficer('Spock', onError, onSuccess);
Listing 19-5.
A Simple Example of the Callback Pattern

How It Works

Callback functions are used often in JavaScript. The second argument in an addEventListener method is a function. Many of the methods used with objects like arrays like forEach have functions passed to them. Using functions as arguments of other functions is possible because functions are first-class objects in JavaScript.
Because functions are first-class objects, they can be executed inside other functions. This type of thinking is known as functional programming . Functions can get executed depending on what is happening in the container function.
This example starts with two functions—onSuccess and onError—one of these functions will be executed based on the outcome of the isFirstOfficer function.
To relate this to error handling, focus on the error. Imagine if an image did not load or the result from the server did not have the data you expected. Here you can throw an error and use it as an argument for your function. This will take the error and execute the function, thereby giving you some way to handle the result.

Can You Create Errors?

Problem

You wonder if you can create errors that suit your needs.

Solution

Error objects can be created and extended, thereby allowing developers to customize errors.

The Code

var rngError = new RangeError('The value is out of range');
        console.log(rngError.message);  //returns The value is out of range
var refError = new ReferenceError('This reference is not valid');
        console.log(refError.message); //returns This reference is not valid
class myCustomError extends Error{
        constructor(message){
                super(message)
        }
}
var myCustomErrorInstance = new myCustomError('This is a Custom Error');
        console.log(myCustomErrorInstance.message);  //returns This is a Custom Error
        console.log(myCustomErrorInstance.stack);    //returns stack trace
try{
        throw new myCustomError('There has been a mistake')
}catch(e){
        console.log(e.message);  //returns There has been a mistake
        console.log(e.stack); //returns stack trace
}
Listing 19-6.
Creating Error Objects and a Custom Error Class

How It Works

Even though JavaScript can return runtime errors, it does give your a way of creating your own error objects. One way is to create an object based on existing error types. These errors work in the same way that runtime errors work. They can be used in try/catch statements and can use the throw keyword.
There may be other times where you’ll need to make an error object that is totally unique. Here, you can create a class (see Chapter 17 about classes) and extend the error that you want to base the custom error on.
This class extends the Error object and passes a message from the constructor to its superclass . Now instances of this class can be used in a try/catch statement.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.105.114