Home > Web Front-end > JS Tutorial > How to handle JavaScript exceptions

How to handle JavaScript exceptions

小云云
Release: 2017-11-28 10:05:24
Original
1845 people have browsed it

Programmers will definitely encounter errors when writing programs. This article is based on the concept of error handling in JavaScript. I hope it will help you when you write JavaScript programs.

Demo Demonstration

The Demo we use can be downloaded from GitHub. When the program is run, the following page will appear:

How to handle JavaScript exceptions

All buttons will trigger errors and throw TypeError. The following is the definition of the module:

// scripts/error.jsfunction error() {var foo = {};return foo.bar();}
Copy after login


An empty object foo is defined in error(), so calling foo.bar() will cause it to be undefined And report an error. Let’s use unit testing to verify:

// tests/scripts/errorTest.jsit('throws a TypeError', function () {should.throws(error, TypeError);});
Copy after login


We use Mocha with Should.js for unit testing.

After you clone the code base and install the dependency packages, you can use npm t to execute tests. Of course, you can also execute a test file, such as: ./node_modules/mocha/bin/mocha tests/scripts/errorTest.js

Believe me, for a dynamic language like JavaScript, no matter who It's easy to encounter errors like this.

Bad handling method

I have abstracted the event processing function corresponding to the button a little simpler, as follows:

// scripts/badHandler.jsfunction badHandler(fn) {try {return fn();} catch (e) { }return null;}
Copy after login

badHandler receives an fn as a callback function, the callback function is called in badHandler. We write the corresponding unit test:

// tests/scripts/badHandlerTest.jsit('returns a value without errors', function() {var fn = function()
{return 1;};var result = badHandler(fn);result.should.equal(1);});it('returns a null with errors', function() 
{var fn = function() {throw new Error('random error');};var result = badHandler(fn);should(result).equal(null);});
Copy after login

You will find that if an exception occurs, badHandler simply returns null. If you match the complete code, you will find the problem:

// scripts/badHandlerDom.js(function (handler, bomb) {var badButton = document.getElementById('bad');
if (badButton) {badButton.addEventListener('click', function () {handler(bomb);console.log('Imagine, getting promoted for hiding mistakes');});
}}(badHandler, error));
Copy after login

If you try-catch it when an error occurs, and then just return null, I can't find what went wrong at all. This fail-silent strategy may lead to UI confusion and data confusion, and you may spend several hours debugging but ignore the code in try-catch, which is the source of the disaster. If the code is so complex that it has multiple levels of calls, it will be almost impossible to find what went wrong. Therefore, we do not recommend using the silent failure strategy, we need a more elegant approach.

Not bad but bad way

// scripts/uglyHandler.jsfunction uglyHandler(fn) {try {return fn();} catch (e) {throw new Error('a new error');}}
Copy after login

The way it handles errors is to catch error e and then throw a new error. This is indeed better than the previous strategy of quiet failure. If something goes wrong, I can go back layer by layer until I find the error e that was originally thrown. Simply throwing an Error ('a new error') has limited information and is not accurate. We customize the error object and send out more information:

// scripts/specifiedError.js// Create a custom errorvar SpecifiedError = function SpecifiedError(message)
 {this.name = 'SpecifiedError';this.message = message || '';this.stack = (new Error()).stack;};
 SpecifiedError.prototype = new Error();SpecifiedError.prototype.constructor = SpecifiedError;
 、//  scripts/uglyHandlerImproved.jsfunction uglyHandlerImproved(fn) {try {return fn();} catch (e)
  {throw new SpecifiedError(e.message);}}// tests/scripts/uglyHandlerImprovedTest.jsit('returns a specified error with errors',
   function () {var fn = function () {throw new TypeError('type error');};should.throws(function () {uglyHandlerImproved(fn);}, 
   SpecifiedError);});
Copy after login


Now , this custom error object contains the original error information and therefore becomes more useful. But because it was thrown again, it was still an unhandled error.

Interception of exceptions

One idea is to surround all functions with try...catch:

function main(bomb) {try {bomb();} catch (e) {// Handle all the error things}}
Copy after login

However, such code will become very Bloated, unreadable, and inefficient. Do you still remember? At the beginning of this article, we mentioned that an exception in JavaScript is just an event. Fortunately, there is a global exception event handling method (onerror).

// scripts/errorHandlerDom.jswindow.addEventListener('error', function (e) {var error = e.error;console.log(error);});
Copy after login

Get stack information

You can send error information to the server:

// scripts/errorAjaxHandlerDom.jswindow.addEventListener('error', function (e)
{var stack = e.error.stack;var message = e.error.toString();if (stack) {message += '\n' + stack;}
var xhr = new XMLHttpRequest();xhr.open('POST', '/log', true);// Fire an Ajax request with error detailsxhr.send(message);});
Copy after login

In order to obtain more detailed error information and save the trouble of processing data , you can also use fundebug's JavaScript monitoring plug-in to quickly access the bug monitoring service in three minutes.

The following is the error message received by the server:

How to handle JavaScript exceptions

If your script is placed under another domain name, if you do not enable CORS, in addition to Script error., you will not see any useful error information. If you want to know the specific solution, please refer to: Script error. Comprehensive analysis.

Asynchronous error handling

Since setTimeout is executed asynchronously, the following code exception will not be caught by try...catch:

// scripts/asyncHandler.jsfunction asyncHandler(fn) {try {// This rips the potential bomb from the current contextsetTimeout(function () {fn();}, 1);} catch (e) { }}
Copy after login


The try...catch statement will only capture exceptions in the current execution environment. But when the above exception is thrown, the JavaScript interpreter is no longer in try...catch, so it cannot be caught. The same goes for all Ajax requests.

We can make a slight improvement and write try...catch into the callback of the asynchronous function:

setTimeout(function () {try {fn();} catch (e) {// Handle this async error}}, 1);
Copy after login

However, such a routine will cause the project to It is full of try...catch, and the code is not concise. Also, the V8 engine that executes JavaScript discourages the use of try...catch in functions. Fortunately, we don't need to do this, the global error handling onerror will catch these errors.

in conclusion

My advice is don't hide errors, be brave enough to throw them out. No one should be ashamed because a bug in the code causes the program to crash. We can interrupt the program and let the user start over. Mistakes are inevitable, how you deal with them is what matters.

The above content is how to deal with JavaScript errors. If you find it useful, please quickly collect it.

Related recommendations:

How to solve the problem of irregular spaces and error reporting in vue.js during the writing process

Perfect solution to PHP installation Implementation steps and error reporting of extending mysqli

MySQL database error: Solution to Too many connections

The above is the detailed content of How to handle JavaScript exceptions. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template