The previous words
Error handling is crucial for web application development. It cannot predict possible errors in advance, and recovery strategies cannot be adopted in advance, which may lead to a poor user experience. Since any javascript error can cause the web page to be unusable, as a developer, you must know when, why, and what will happen. This article will introduce the error handling mechanism in javascript in detail
error object
The error object is an object containing error information and is a native object of javascript. When an error occurs during code parsing or running, the javascript engine will automatically generate and throw an instance of the error object, and then the entire program will be interrupted where the error occurs.
console.log(t);//Uncaught ReferenceError: t is not defined
ECMA-262 specifies that an error object includes two properties: message and name. The message attribute saves the error message, while the name attribute saves the error type
//Generally, try-catch statement is used to catch error try{ t;}catch(ex){ console.log(ex.message);//t is not defined console.log(ex.name);//ReferenceError}The browser also expanded the properties of the error object and added other relevant information. Among them, the most implemented by browser manufacturers is the stack attribute, which indicates stack trace information (safari does not support it)
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 an error object. If the message parameter is specified, the error object will use it as its message property; if not specified, it will use a predefined default string as the value of the property
new Error();new Error(message); //Generally, use throw statement to throw an 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: errorMessageWhen the Error() constructor is called directly like a function without using the new operator, its behavior is the same as when the new operator is called
Error();Error(message); throw Error('test');//Uncaught Error: testthrow Error();//Uncaught ErrorThe error object has a toString() method, which returns the message attribute of the error object.
var test = new Error('testError');console.log(test.toString());//'Error: testError'error type
There are many types of errors that may occur during code execution. Each error has a corresponding error type, and when an error occurs, an error object of the corresponding type will be thrown. ECMA-262 defines the following 7 error types:
ErrorEvalError(evalError)RangeError(rangeError)ReferenceError(referenceError)SyntaxError(syntaxError)TypeError(typeError)URIError(URIError)
Where, Error is the base type, and other error types are inherited from this type. Therefore, all error types share a set of the same properties. Error type errors are rare, and if there are, they are also thrown by the browser; the main purpose of this base type is for developers to throw custom errors
【EvalError(eval error)】
When the eval function is not executed correctly, an EvalError error will be thrown. This error type no longer appears in ES5, but will continue to be preserved to ensure compatibility with previous codes.
【RangeError(RangeError)】
An error of the RangeError type will be triggered when a value exceeds the corresponding range, mainly including exceeding the array length range and exceeding the number value range.
new Array(-1);//Uncaught RangeError: Invalid array lengthnew Array(Number.MAX_VALUE);//Uncaught RangeError: Invalid array length(1234).toExponential(21);//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 will be triggered when referring to an unexistent variable or lvalue type error.
a;//Uncaught ReferenceError: a is not defined1++;//Uncaught ReferenceError: Invalid left-hand side expression in postfix operation
【SyntaxError(SyntaxError)】
When the syntax rules are not met, a SyntaxError will be thrown (syntax error)
//Variable name error var 1a;//Uncaught SyntaxError: Unexpected number// Missing bracket console.log 'hello');//Uncaught SyntaxError: Unexpected string
【TypeError(type error)】
TypeError type error will be caused when unexpected types are stored in variables, or when accessing non-existent methods. Although the causes of errors are diverse, ultimately, it is because the type of variable does not meet the requirements when performing a specific type of operation.
var o = new 10;//Uncaught TypeError: 10 is not a constructoralert('name' in true);//Uncaught TypeError: Cannot use 'in' operator 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 thrown when the parameters of URI-related functions are incorrect. It mainly involves six functions: encodeURI(), decodeURI(), encodeURIComponent(), decodeURIComponent(), escape() and unescape().
decodeURI('%2');// URIError: URI malformederror event
Any errors that are not processed through try-catch will trigger the error event of the window object
The error event can receive three parameters: error message, URL where the error is located, and line number. In most cases, only error messages are useful because the URL only gives the location of the document, and the line number refers to a line of code that can be from embedded JavaScript code or from an external file.
To specify an error event handler, you can use DOM0 level technology or use the standard format of 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 onerror. If the return value is false, an error message is displayed in the console; if the return value is true, it is not displayed
//The console displays error message window.onerror = function(message,url,line){ alert(message); return false;}a;//The 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 avoid browser reporting errors. Ideally, you shouldn't use it whenever possible. As long as you can use the try-catch statement appropriately, there will be no errors handed to the browser and the error event will not be triggered.
The image also supports error events. As long as the URL in the src characteristic of the image cannot return the recognized image format, an error event will be triggered. At this time, the error event follows the DOM format and returns an event object targeting the image as the target
A warning box appears when the image is loaded. When an error event occurs, the image download process has ended, which means that it cannot be downloaded again.
var image = new Image();image.src = 'smilex.gif';image.onerror = function(e){ console.log(e);}throw statement and throw error
The throw statement is used to throw an error. When an error is thrown, you must specify a value to the throw statement. What type is this value? There is no requirement.
[Note] The process of throwing an error is blocked, and subsequent code will not be executed
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 do you take me for?');throw new RangeError('sorry,you just don/'t have the range.');throw new EvalError('That doesn/'t evaluate.');throw new URIError('URI, is that you?');throw new ReferenceError('you didn/'t cite your references properly');Using prototype chains can also create custom error types by inheriting Error (prototype chains are introduced in Chapter 6). At this point, you need to specify the name and message attributes for the newly created error type
The browser treats custom error types inherited from Error just like other error types. Creating a custom error is useful if you want to catch the error you throw and treat it differently from the browser error.
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 will stop executing immediately. The code will continue to execute only if a try-catch statement captures the thrown value.
A more detailed explanation is: when an exception is thrown, the javascript interpreter will immediately stop the currently executing logic and jump to the nearby exception handler. The exception handler is written in 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 will check 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 will be propagated upwards to the code that calls the function. In this way, the exception will be propagated upward along the lexical structure of the javascript method and the call stack. If no exception handler is found, javascript will handle the exception as a program error and report it to the user
Try catch statement and catch error
ECMA-262 Edition 3 introduces the try-catch statement as a standard way to handle exceptions in JavaScript, used to catch and handle errors
Among them, the try clause defines the code block where the exceptions that need to be processed are located. The catch clause follows the try clause. When an exception occurs somewhere in the try block, the code logic inside the catch is called. The catch clause is followed by the finally block, where the cleaning code is placed. Regardless of whether an exception occurs in the try block, the logic inside the finally block will always be executed. Although catch and finally are optional, the try clause requires at least one of the two to form a complete statement with it.
All try/catch/finally statement blocks need to be enclosed with curly braces. Braces here are required. Even if there is only one statement in the clause, curly braces cannot be omitted.
try{ // Generally speaking, the code here will not cause any problems // But sometimes an exception will be thrown directly by the throw statement or indirectly thrown by calling a method } catch(e){ // If and only if an exception is thrown by the try statement block, the code here will be executed // Here you can obtain a reference to the Error object or other values thrown by the local variable e // The code here can handle this exception for some reason, or ignore this exception, and you can also re-throw the exception by the throw statement } finally{ // Regardless of whether the try statement throws an exception, the logic in finally will always be executed, and the way to terminate the try statement block is: //1. Terminate normally. After executing the last statement of the statement block //2. Terminate through break, continue or return statement //3. Throw an exception, the exception is caught by the catch clause //4. Throw an exception, the exception is not caught, continue to propagate upward}Generally, put all the code that may throw errors in the try statement block, and put the code used for error handling in the catch block
If any code in the try block error occurs, the code execution process will be immediately exited and the catch block will be executed. At this time, the catch block will receive an object with error message. The actual information contained in this object will vary from browser to browser, but the common is that there is a message attribute that stores the error message
[Note] Be sure to name the error object. If emptying it, a syntax error will be reported.
try{ q;}catch(error){ alert(error.message);//q is not defined}//Uncaught SyntaxError: Unexpected token )try{ q;}catch(){ alert(error.message);}catch accepts a parameter indicating 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 error happenedAfter the catch code block catches the error, the program will not be interrupted and will continue to execute according to the normal process.
try{ throw "Error";} catch (e) { console.log(111);}console.log(222);// 111// 222In order to catch different types of errors, judgment statements 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, once the finally clause is used, its code will be executed no matter what. In other words, all the code in the try statement block is executed normally, and finally clauses will be executed; if the catch statement block is executed due to an error, the finally clause will still be executed. As long as the code contains finally clauses, no matter what code is contained in the try or catch statement block - or even the return statement, the execution of the finally clause will not be prevented.
//The error is not caught because there is no catch statement block. After executing the finally code block, the program interrupts the function cleansUp() where the error is thrown. function cleansUp() { try { throw new Error('Error...'); console.log('This line will not be executed'); } finally { console.log('Complete the cleanup work'); }}cleansUp();// Complete the cleanup work// Error: An error... function testFinnally(){ try{ return 2; }catch(error){ return 1; } finally{ return 0; }}testFinnally();//0[Note] 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 delayed until the end of the finally code block before executing console.log(2); // It will not run} finally { console.log(3); return false; // This sentence will overwrite the previous sentence return console.log(4); // It will not run} console.log(5); // It will not run}var result = f();// 0// 1// 3console.log(result);// false【tips】Block-level scope
A common use of try-catch statements is to create block-level scopes where declared variables are only valid inside the catch
ES6 introduces the let keyword to create a block-level scope for the variables it declares. However, in the current situation of ES3 and ES5, try-catch statements are often used to achieve similar effects
From the following code, e only exists inside the catch clause, and an error will be thrown when trying to reference it from elsewhere.
try{ throw new Error();//throttling an error}catch(e){ console.log(e);//Error(…)}console.log(e);//Uncaught ReferenceError: e is not definedThe core of common error handling is to first know what errors will happen in the code. Since javaScript is loosely typed and does not verify the parameters of the function, the error will only occur during the code. Generally speaking, three types of errors need to be paid attention to: type conversion error, data type error, and communication error
【Type conversion error】
Type conversion error occurs when using an operator, or using another language structure of data types that may automatically convert values.
The flow control statement is prone to type conversion errors. Statements like if will automatically convert any value to a boolean before determining the next operation. Especially if statements, if used improperly, they are most likely to make mistakes.
Unused named variables are automatically assigned undefined values. The undefined value can be converted to a boolean value false, so the if statement in the following function is actually only applicable to cases where the third parameter is provided. The problem is that it is not only undefined to be converted to false, nor is it only string values that can be converted to true. For example, if the third parameter is the value 0, the test of the if statement will fail, and the test of the logarithmic value 1 will pass
function concat(str1,str2,str3){ var result = str1 + str2; if(str3){ //Absolutely don't result += str3; } return result;}Using non-boolean values in flow control statements is an extremely common source of errors. To avoid such errors, it is necessary to pass in boolean values when conditions are compared. In fact, performing some form of comparison can achieve this
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 will not be compared to ensure that their data type is correct until variables and function parameters are used. In order to ensure that data type errors will not occur, only appropriate data type detection code can be written. Data type errors are most likely to occur when passing unexpected values to plot functions
//Insecure functions, any non-array value will cause error function reverseSort(values){ if(values){ values.sort(); values.reverse(); }}Another common mistake is to compare parameters with null values. Comparing with null only ensures that the corresponding values are not null and undefined. To ensure that the value passed in is valid, it is not enough to detect null values only
//Insecure functions, any non-array value will cause error function reverseSort(values){ if(values != null){ values.sort(); values.reverse(); }}If an object containing the sort() method (rather than an array) is passed, it will pass the detection, but an error may occur when calling the reverse() function
//Insecure functions, any non-array value will cause error function reverseSort(values){ if(typeof values.sort == 'function'){ values.sort(); values.reverse(); }}In case you know exactly what type you should pass in, it is best to use instanceof to detect its data type
//Safe, non-array values are ignored function reverseSort(values){ if(values instanceof Array){ values.sort(); values.reverse(); }}【Communication Error】
With the rise of Ajax programming, it has become commonplace for web applications to dynamically load information or functionality during their life cycle. However, any communication between JavaScript and the server may cause an error
The most common problem is that data is not encoded using encodeURIComponent() before sending it to the server
//Error http://www.yourdomain.com/?redir=http://www.sometherdomain.com?a=b&c=d//Call encodeURIComponent() for all strings after 'redir=' can solve this problem http://www.yourdomain.com/?redir=http:%3A%2F%2Fwww.sometherdomain.com%3Fa%3Db%26c%3Dd
The above article comprehensively understands the error handling mechanism in JavaScript. This is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.