When the JavaScript engine executes JavaScript code, various exceptions may occur, such as syntax exceptions, missing features in the language, due to abnormal output from the server or user resulting in anomalies.
The Javascript engine is single-threaded, so once an exception is encountered, the Javascript engine usually stops execution, blocks subsequent code and throws an exception message, so For foreseeable exceptions, we should catch and correctly display them to users or developers.
throw and Promise.reject() can throw string type exceptions, and can throw a Error Exception of object type.
A Error object type exception not only contains an exception information, but also contains a traceback stack so that you can easily find the number of lines of code where the error occurs through the traceback stack.
So it is recommended to throw Error object type exceptions instead of string type exceptions.
Create your own exception constructor
function MyError(message) { var instance = new Error(message); instance.name = 'MyError'; Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); return instance; } MyError.prototype = Object.create(Error.prototype, { constructor: { value: MyError, enumerable: false, writable: true, configurable: true } }); if (Object.setPrototypeOf) { Object.setPrototypeOf(MyError, Error); } else { MyError.__proto__ = Error; } export default MyError;
Throw custom exception types in code and catch them
try { throw new MyError("some message"); } catch(e){ console.log(e.name + ":" + e.message); }
throw expression;
throw statement is used to throw a user-defined exception. Execution of the current function will be stopped (statements after throw will not be executed), and control will be passed to the first catch block in the call stack. If there is no catch block in the caller function, the program will terminate.
try { console.log('before throw error'); throw new Error('throw error'); console.log('after throw error'); } catch (err) { console.log(err.message); } // before throw error // throw error
try { try_statements } [catch (exception) { catch_statements }] [finally { finally_statements }]
try/catch is mainly used to catch exceptions. The try/catch statement contains a try block, and at least one catch block or a finally block. The following are three forms Statement of try:
try...catch
try...finally
try...catch...finally
try Put statements or functions that may generate exceptions in the block
# The##catch block contains the statement to be executed. When an exception is thrown in the try block, the catch block will capture the exception information and execute# Code in the ##catch block, if no exception is thrown in the try block, this catch block will be skipped. The
finally block is executed after the try block and the catch block. It is always executed regardless of whether an exception is thrown or caught. When exception information is thrown in the finally block, the exception information in the try block will be overwritten. try {
try {
throw new Error('can not find it1');
} finally {
throw new Error('can not find it2');
}
} catch (err) {
console.log(err.message);
}
// can not find it2
block, then this value will become the return value of the entire try-catch-finally, regardless of whether there is a The return statements are in try and catch. This includes exceptions thrown within catch blocks. function test() {
try {
throw new Error('can not find it1');
return 1;
} catch (err) {
throw new Error('can not find it2');
return 2;
} finally {
return 3;
}
}
console.log(test()); // 3
. The
try/catchstatement used in the V8 (the same situation may occur in other JS engines) function cannot be optimized by the V8 compiler. Refer to http://www.html5rocks.com/en/tutorials/speed/v8/window.onerror
function, uncaught exceptions generated by other codes in the program are often captured by the listening function registered above window.onerror. And at the same time capture some information about the exception. window.onerror = function (message, source, lineno, colno, error) { }
:Exception message (string)
:Exception occurred Script URL (string)
: The line number where the exception occurred (number)
: The column number (number) where the exception occurred
: Error object (object)
, which is an Error object with a traceback stack
try/catch cannot catch exceptions in asynchronous code, but it will throw the exception globally and window.onerror can catch it. try {
setTimeout(() => {
throw new Error("some message");
}, 0);
} catch (err) {
console.log(err);
}
// Uncaught Error: some message
window.onerror = (msg, url, line, col, err) => {
console.log(err);
}
setTimeout(() => {
throw new Error("some message");
}, 0);
// Error: some message
can detect exceptions in script files referenced from other domains and mark these exceptions as Script error. If you don't want to process these script files imported from other domains, you can filter them out through the 在Chrome中,如果你想通过 window.onerror 来获取到完整的跨域异常信息,那么这些跨域资源必须提供合适的跨域头信息。 在 JavaScript 函数中,只有 return / yield / throw 会中断函数的执行,其他的都无法阻止其运行到结束的。 在 resolve / reject 之前加上 return 能阻止往下继续运行。 without use 无论是 try/catch 还是 promise 都能捕获到的是“同步”异常 reject 是回调,而 throw 只是一个同步的语句,如果在另一个异步的上下文中抛出,在当前上下文中是无法捕获到的。 因此在 Promise 中使用 reject 抛出异常。否则 catch 有可能会捕捉不到。 因为 Promise 可以延后调用 catch 方法,若在抛出 reject 时未调用 catch 进行捕捉,但稍后再次调用 catch,此时会触发 rejectionhandled 事件。 代码中抛出的异常,一种是要展示给用户,一种是展示给开发者。 对于展示给用户的异常,一般使用 alert 或 toast 展示;对于展示给开发者的异常,一般输出到控制台。 在一个函数或一个代码块中可以把抛出的异常统一捕捉起来,按照不同的异常类型以不同的方式展示,对于。 需要点击确认的异常类型: 弹窗提示的异常类型: 提示开发者的异常类型: 异常处理器: The above is the detailed content of Explanation of JavaScript exception handling. For more information, please follow other related articles on the PHP Chinese website!Script error
tag in the program. However, in Firefox, Safari or IE11, cross-domain JS exceptions will not be introduced. Even in Chrome, if you use try/catch
to surround these nasty codes, Chrome will no longer detect it. to these cross-domain exceptions. Promise中的异常
Promise中抛出异常
new Promise((resolve,reject)=>{
reject();
})
Promise.resolve().then((resolve,reject)=>{
reject();
});
Promise.reject();
throw expression;
Promise中捕捉异常
promiseObj.then(undefined, (err)=>{
catch_statements
});
promiseObj.catch((exception)=>{
catch_statements
})
return
:Promise.resolve()
.then(() => {
console.log('before excute reject');
reject(new Error('throw error'));
console.log('after excute reject');
})
.catch((err) => {
console.log(err.message);
});
// before excute reject
// throw error
// after excute reject
return
:Promise.resolve()
.then(() => {
console.log('before excute reject');
return reject(new Error('throw error'));
console.log('after excute reject');
})
.catch((err) => {
console.log(err.message);
});
// before excute reject
// throw error
Throw or Reject
Promise.resolve()
.then(() => {
setTimeout(()=>{
throw new Error('throw error');
},0);
})
.catch((err) => {
console.log(err);
});
// Uncaught Error: throw error
Promise.resolve()
.then(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('throw error'));
}, 0);
});
})
.catch((err) => {
console.log(err);
});
// Error: throw error
window.onunhandledrejection
window.onunhandledrejection
与 window.onerror
类似,在一个JavaScript Promise 被 reject 但是没有 catch 来捕捉这个 reject时触发。并且同时捕获到一些关于异常的信息。window.onunhandledrejection = event => {
console.log(event.reason);
}
event
事件是 PromiseRejectionEvent 的实例,它有两个属性:event.promise
:被 rejected 的 JavaScript Promiseevent.reason
:一个值或 Object 表明为什么 promise 被 rejected,是 Promise.reject() 中的内容。window.rejectionhandled
window.onrejectionhandled = event =>
{
console.log('rejection handled');
}
let p = Promise.reject(new Error('throw error'));
setTimeout(()=>{
p.catch(e=>{console.log(e)});
},1000);
// Uncaught (in promise) Error: throw error
// 1秒后输出
// Error: throw error
// rejection handled
统一异常处理
ensureError.jsfunction EnsureError(message = 'Default Message') {
this.name = 'EnsureError';
this.message = message;
this.stack = (new Error()).stack;
}
EnsureError.prototype = Object.create(Error.prototype);
EnsureError.prototype.constructor = EnsureError;
export default EnsureError;
toastError.jsfunction ToastError(message = 'Default Message') {
this.name = 'ToastError';
this.message = message;
this.stack = (new Error()).stack;
}
ToastError.prototype = Object.create(Error.prototype);
ToastError.prototype.constructor = ToastError;
export default ToastError;
devError.jsfunction DevError(message = 'Default Message') {
this.name = 'ToastError';
this.message = message;
this.stack = (new Error()).stack;
}
DevError.prototype = Object.create(Error.prototype);
DevError.prototype.constructor = DevError;
export default DevError;
抛出普通异常时,可以带上 stackoverflow 上问题的列表,方便开发者查找原因。
errorHandler.jsimport EnsureError from './ensureError.js';
import ToastError from './toastError.js';
import DevError from './devError.js';
import EnsurePopup from './ensurePopup.js';
import ToastPopup from './toastPopup.js';
function errorHandler(err) {
if (err instanceof EnsureError) {
EnsurePopup(err.message);
} else if (err instanceof ToastError) {
ToastPopup(err.message);
}else if( err instanceof DevError){
DevError(err.message);
}else{
error.message += ` https://stackoverflow.com/questions?q=${encodeURI(error.message)}`
console.error(err.message);
}
}
window.onerror = (msg, url, line, col, err) => {
errorHandler(err);
}
window.onunhandledrejection = event =>{
errorHandler(event.reason);
};
export default errorHandler;