Previous words
Error handling is critical for Web application development, not anticipating possible errors ahead of time, and not taking a recovery strategy in advance, which can lead to poor user experience. Because any JavaScript error can cause a Web page to become unusable, as a developer, you must know when it is possible to make an error, why it is wrong, and what will happen. This article will detail the error handling mechanism in JavaScript
Error Object
The Error object is an object that contains the wrong information and is the native object of JavaScript. When code parsing or runtime errors occur, the JavaScript engine automatically generates and throws an instance of an Error object, and then the entire program breaks down where the error occurred
Console.log (t);//uncaught referenceerror:t is not defined
ECMA-262 specifies that the Error object consists of two attributes: message and name. The message property holds the error message, and the Name property holds the error type
In general, use the Try-catch statement to catch the error try{ t;} catch (ex) { console.log (ex.message);//t is not defined console.log (ex.name);//referenceerror}
The browser also extends the properties of the Error object and adds other relevant information. The most common browser vendors are the stack attribute, which represents the stack trace information (Safari does not support)
try{ t;} catch (ex) { console.log (ex.stack);//@file:///d:/wamp/www/form.html:12:2}
Of course, you can use the error () constructor to create the wrong object. If you specify the message parameter, the Error object will use it as its message property, and, if not specified, it uses a predefined default string as the value of the property
New error (); New error (message);
In general, use the throw statement to throw the error throw new error (' Test ');//uncaught error:testthrow new error ();//uncaught error
function Usererror (message) { this.message = message; THIS.name = "Usererror";} Usererror.prototype = new Error (); UserError.prototype.constructor = Usererror;throw New Usererror ("errormessage");//uncaught usererror:errormessage
When you call the error () constructor directly like a function without using the new operator, it behaves as if it were called with the new operator
Error (); Error (message);
Throw error (' Test ');//uncaught error:testthrow error ();//uncaught error
The Error object has a ToString () method that returns the ' ERROR: ' + Error object's Message property
var test = new Error (' Testerror '); Console.log (test.tostring ());//' Error:testerror '
Error type
There are several types of errors that can occur during code execution. Each error has a corresponding error type, and when an error occurs, the corresponding type of error object is thrown. ECMA-262 defines the following 7 types of errors:
Errorevalerror (eval error) Rangeerror (range error) referenceerror (reference error) SyntaxError (syntax error) TypeError (wrong type) Urierror (URI error)
Where error is a base type, and other error types inherit from that type. Therefore, all error types share a set of identical properties. Errors of type error are seldom seen, if any are also thrown by the browser; The primary purpose of this base type is for developers to throw custom errors
"Evalerror (eval error)"
An evalerror error is thrown when the eval function is not executed correctly. The error type is no longer present in ES5, only to ensure compatibility with the previous code.
"Rangeerror (range error)"
Rangeerror types of errors are triggered when a value goes out of range, mainly including exceeding the range of array lengths and exceeding the value range of a number.
New Array ( -1);//uncaught rangeerror:invalid array lengthnew Array (number.max_value);//uncaught rangeerror:invalid Array length (1234). Toexponential,//uncaught rangeerror:toexponential () argument must be between 0 and 20 (1234). Toexponential ( -1);////uncaught rangeerror:toexponential () argument must be between 0 and 20
"Referenceerror (reference error)"
Referenceerror (reference error) is triggered when a non-existent variable or lvalue (lvalue) type error is referenced
A;//uncaught referenceerror:a is isn't defined1++;//uncaught referenceerror:invalid left-hand side expression in Postfix o Peration
"SyntaxError (syntax error)"
SyntaxError (syntax error) is thrown when a grammar rule is not met
Variable name error var 1a;//uncaught syntaxerror:unexpected number//missing parentheses console.log ' hello ');//uncaught syntaxerror:unexpected String
"TypeError (type Error)"
A TypeError type error is caused when an unexpected type is stored in a variable, or when a method that does not exist is accessed. The cause of the error is varied, but it boils down to the fact that the type of the variable does not conform to the requirements when performing certain types of operations
var o = new 10;//uncaught typeerror:10 is not a constructoralert (' name ' in true);//uncaught typeerror:cannot use ' in ' Op Erator to search for ' name ' in TrueFunction.prototype.toString.call (' name ');//uncaught TypeError: Function.prototype.toString is not generic
"Urierror (URI error)"
Urierror is an error that is thrown when the parameters of a URI-related function are incorrect, mainly involving encodeURI (), decodeURI (), encodeURIComponent (), decodeURIComponent (), Escape () and Unescape () six of these functions
decodeURI ('%2 ');//Urierror:uri Malformed
Error Event
Any error that is not handled by Try-catch will trigger the error event of the Window object
The error event can receive three parameters: a fault message, the URL where the error occurred, and the line number. In most cases, only the error message is useful, because the URL simply gives the location of the document, and the line number refers to a line of code that is either derived from the embedded JavaScript code, or it may originate from an external file
To specify onerror event handlers, you can use DOM0-level techniques or use the standard format for DOM2-level events
DOM0 Level window.onerror = function (message,url,line) { alert (message);} DOM2 level Window.addeventlistener ("Error", function (message,url,line) { alert (message);});
Whether the browser displays a standard error message depends on the return value of the onerror. If the return value is False, an error message is displayed in the console, and if the return value is true, the
Console displays error message Window.onerror = function (message,url,line) { alert (message); return false;} a;//Console does not display error message Window.onerror = function (message,url,line) { alert (message); return true;} A
This event handler is the last line of defense to prevent the browser from reporting errors. Ideally, it should not be used as long as it is possible. As long as the Try-catch statement is properly used, no error is given to the browser, and the error event is not triggered
The image also supports error events. The error event is triggered whenever the URL in the src attribute of the image cannot return an image format that can be recognized. The error event at this time follows the DOM format and returns an event object that targets the image
An alert box appears when an image fails to load. When the error event occurs, the image download process is finished, which is no longer downloaded again
var image = new Image (); image.src = ' smilex.gif '; image.onerror = function (e) { console.log (e);}
Throw statement with throw error
The throw statement is used to throw an error. When you throw an error, you must specify a value for the throw statement, what type of value is it, no requirement
[note] The process of throwing an error is blocked and subsequent code will not execute
Throw 12345;throw ' Hello World '; throw true;throw {name: ' JavaScript '};
You can use the throw statement to manually throw an Error object
throw new Error (' Something bad happened '), throw new SyntaxError (' I don\ ' t like your syntax. '); throw new TypeError (' What type of variable does you take me for? '); throw new Rangeerror (' sorry,you just don\ ' t has the range. '); throw new Evalerror (' that doesn\ ' t evaluate. '); throw new Urierror (' URI, is that '? '); throw new Referenceerror (' You didn\ ' t cite your references properly ');
The prototype chain can also be used to create custom error types by inheriting error. At this point, you need to specify the name and message property for the newly created error type
The browser treats the custom error type that inherits from error, just as it does with other error types. It is useful to create custom errors if you want to capture the errors you throw and treat them differently from browser errors.
function customerror (message) { this.name = ' customerror '; this.message = message;} Customerror.prototype = new Error (); throw new Customerror (' My message ');
When a throw statement is encountered, the code stops executing immediately. The code will continue to execute only if a Try-catch statement captures the thrown value
A more detailed explanation is that when an exception is thrown, the JavaScript interpreter immediately stops the currently executing logic and jumps to the nearest exception handler. The exception handler is written using the catch clause of the Try-catch statement. If the code block that throws the exception does not have an associated catch clause, the interpreter examines the higher-level closed code block to see if it has an associated exception handler. And so on until an exception handler is found. If the function that throws the exception does not handle its Try-catch statement, the exception propagates up to the code that called the function. In this case, the exception propagates upward along the lexical structure and call stack of the JavaScript method. If no exception handler is found, JavaScript treats the exception as a program error and reports to the user
Try catch statement and catch error
ECMA-262 version 3rd introduces the Try-catch statement as a standard way to handle exceptions in JavaScript for capturing and handling errors
Where the TRY clause defines the code block where the exception is to be handled. After the catch clause follows the TRY clause, the code logic inside the catch is called when an exception occurs somewhere inside the try block. The catch clause follows the finally block, where the cleanup code is placed, regardless of whether an exception is generated in the try block, and the logic in the finally block is always executed. Although both catch and finally are optional, a try clause requires at least one of the two to form a complete statement
try/catch/finally statement blocks need to be enclosed in curly braces, where curly braces are required, even if there is only one statement in the clause that cannot omit the curly braces
try{ //In general, the code here will go from beginning to end without generating any problems //But sometimes throwing an exception, either thrown directly by the throw statement, or indirectly thrown by invoking a method}catch (e) { // If and only if the try statement block throws an exception, the code is executed here //A reference to the Error object or other value thrown by the local variable e can be obtained here //The code block here can handle the exception for some reason or ignore the exception. You can also re-throw the exception through the throw statement}finally{ //Regardless of whether the try statement throws an exception, finally the logic will always execute, the way to terminate the TRY statement block is: //1, normal termination, execute the last statement of the statement block ///2, terminating by break, continue or Return statement //3, throwing an exception, exception caught by catch clause //4, throwing an exception, exception not caught, continue to propagate up}
In general, put all the code that might throw the error in the TRY statement block, and put the code for error handling in the CATCH block
If any code in the try block has an error, it exits the code execution immediately and then executes the catch block. At this point, the catch block receives an object with an error message, and the actual information contained in the object will vary by browser, but in common there is a message property that holds the error message
[note] Be sure to give the Error object a name, empty will report a syntax error
try{ Q;} catch (Error) { alert (error.message);//q is not defined}//uncaught syntaxerror:unexpected token) try{ q;} catch () { alert (error.message);}
Catch takes a parameter that represents the value thrown by the try code block
function Throwit (Exception) { try { throw exception; } catch (e) { console.log (' caught: ' + E); }} Throwit (3);//Caught:3throwit (' hello ');//Caught:hellothrowit (new error (' An error happened '));//Caught:Error:An Erro R happened
The catch block catches the error, the program is not interrupted, and continues with the normal process
try{ Throw "error";} catch (e) { console.log (111);} Console.log (222);//111//222
To catch different types of errors, a judgment statement can be added to the catch code block
try { foo.bar ();} catch (e) { if (e instanceof evalerror) { Console.log (e.name + ":" + e.message); } else if (e instanceof rangeerror) { Console.log (e.name + ":" + e.message); } // ...}
Although the finally clause is optional in the Try-catch statement, the finally clause will be executed in any case, once it is used. In other words, the code in the TRY statement block executes normally, and the finally clause executes, and if a catch statement block is executed because of an error, the finally clause is also executed. Whenever a finally clause is included in the code, no matter what code is included in the try or catch statement block-even the return statement-the execution of the finally clause is not prevented
The error is not captured because there is no catch statement block. After the finally code block is executed, the program interrupts the function Cleansup () { try { throw new error (' Error ... ') where the error was thrown; Console.log (' This line will not execute '); } finally { Console.log (' Finish cleanup work ');} } Cleansup ();//complete cleanup work//error: Error ...
function testfinnally () { try{ return 2; } catch (Error) { return 1; } finally{ return 0;} } Testfinnally ();//0
[Note that the value of the count of the]return statement is obtained before the finally code block is run.
var count = 0;function Countup () { try { return count; } finally { count++; }} Countup ();//0console.log (count);//1
function f () { try { console.log (0); Throw "bug"; } catch (e) { console.log (1); return true; This sentence would have been deferred until finally the end code block is executed console.log (2);//Will not run } finally { console.log (3); return false; This sentence will overwrite the previous sentence return Console.log (4);//Will not run } console.log (5);//will not run}var result = f ();//0//1//3
Console.log (result);//False
"Tips" block-level scopes
A common use of the Try-catch statement is to create a block-level scope in which the declared variable is valid only within the catch
ES6 introduces the Let keyword to create a block-level scope for the variables it declares. However, in the current case of ES3 and ES5, try-catch statements are often used to achieve similar effects
The following code shows that e exists only inside the catch clause and throws an error when trying to reference it from elsewhere
try{ throw new error ()//Throws error}catch (e) { console.log (e);//error (...)} Console.log (e);//uncaught referenceerror:e is not defined
In the Ie8-browser, the Error object caught in the catch statement is added to the variable object of the execution environment, not the variable object of the Catch statement. In other words, the Error object can be accessed even outside the catch block. IE9 fixed the problem.
Try{ A;} catch (e) { console.log (1);} The standard browser will prompt for undefined, and the ie8-browser will display the Error object Console.log (e);
Common errors
The core of error handling is to first know what is going wrong in the code. Because JavaScript is loosely typed and does not validate the parameters of a function, errors occur only during code. In general, there are three types of errors to follow: type conversion errors, data type errors, communication errors
"Type conversion Error"
Type conversion errors occur when you use an operator, or when you use a language structure that uses other data types that can automatically convert values
The place where a type conversion error is prone is the flow control statement. Statements like if will automatically convert any value to a Boolean value before determining the next action. Especially if statements, which are most prone to errors if used improperly
Unused named variables are automatically assigned the undefined value. The undefined value can be converted to a Boolean value of false, so the IF statement in the following function actually applies only to cases where the third argument is provided. The problem is that not only undefined is converted to false, it is not only the string value that can be converted to true. For example, if the third argument is a numeric value of 0, then the test of the IF statement will fail, and a test of value 1 will pass
function Concat (STR1,STR2,STR3) { var result = str1 + str2; if (STR3) {//Never do such a result + = STR3; } return result;}
Using non-Boolean values in flow control statements is a very common source of error. To avoid such errors, it is necessary to actually pass in the Boolean value when the condition is compared. In fact, performing some form of comparison can achieve this goal
function Concat (STR1,STR2,STR3) { var result = str1 + str2; if (typeof Str3 = = ' string ') {//More suitable result + = STR3; } return result;}
"Data type Error"
JavaScript is loosely typed, and they are not compared before using variables and function parameters to ensure that their data types are correct. To ensure that data type errors do not occur, only the appropriate data type detection code can be written. Data type errors are most likely to occur in cases where unexpected values are passed to the function
Unsafe functions, any non-array value will result in error function Reversesort (values) { if (values) { values.sort (); Values.reverse (); }}
Another common mistake is to compare a parameter to a null value. Comparisons with NULL only ensure that the corresponding values are not null and undefined. To ensure that the value passed in is valid, it is not sufficient to detect only null values
Unsafe function, any non-array value will result in error function Reversesort (values) { if (values! = null) { values.sort (); Values.reverse (); }}
If you pass in an object that contains the sort () method (instead of an array), it is detected, but an error may occur when you call the reverse () function
Unsafe function, any non-array value will result in error function Reversesort (values) { if (typeof values.sort = = ' function ') { values.sort (); Values.reverse (); }}
In cases where you know exactly what type to pass in, it's best to use instanceof to detect its data type
Safe, non-array values are ignored by function Reversesort (values) { if (values instanceof Array) { values.sort (); Values.reverse (); }}
"Communication Error"
With the advent of Ajax programming, it has become commonplace for Web applications to dynamically load information or functionality throughout their lifecycle. However, any communication between JavaScript and the server can cause errors
The most common problem is that data is not encoded using encodeURIComponent () before sending the data to the server
Error http://www.yourdomain.com/?redir=http://www.sometherdomain.com?a=b&c=d//for ' redir= ' All subsequent strings call encodeURIComponent () to resolve the problem http://www.yourdomain.com/?redir=http:%3A%2F%2Fwww.sometherdomain.com% 3fa%3db%26c%3dd
Resources
"1" es5/errors https://www.w3.org/html/ig/zh/wiki/ES5/errors
"2" Ruan one peak JavaScript standard reference Tutorial-error handling mechanism http://javascript.ruanyifeng.com/grammar/error.html
"3" JavaScript authoritative Guide (6th edition), part III JavaScript core reference
"4" JavaScript Advanced Programming (3rd Edition), chapter 17th error Handling and debugging
Error handling mechanisms in JavaScript