Mastering JavaScript Error Handling: Best Practices and Real‑World Examples
This article explores proper error handling in browser‑side JavaScript, comparing flawed silent‑failure approaches with robust try‑catch and global onerror techniques, and demonstrates how to test, debug, and report exceptions in both synchronous and asynchronous code.
Proper Error Handling in JavaScript
This guide explains how to handle exceptions in browser‑side JavaScript, illustrating both good and bad practices with concrete code examples and unit tests.
Example
A function that throws a TypeError and its Mocha test:
function error() {
var foo = {};
return foo.bar();
} it('throws a TypeError', function () {
should.throws(target, TypeError);
});Bad Handling
A handler that silently returns null on error:
function badHandler(fn) {
try {
return fn();
} catch (e) { }
return null;
}Unit tests show it returns a value when no error occurs and null when an exception is thrown.
Improved Handling
A handler that re‑throws a new error, preserving stack information:
function uglyHandler(fn) {
try {
return fn();
} catch (e) {
throw Error('a new error');
}
}Leaving the Call Stack
Using a global onerror listener to catch any uncaught exception:
if (window.addEventListener) {
window.addEventListener('error', function (e) {
var error = e.error;
console.log(error);
});
} else if (window.attachEvent) {
window.attachEvent('onerror', function (e) {
var error = e.error;
console.log(error);
});
} else {
window.onerror = function (e) {
var error = e.error;
console.log(error);
};
}This captures errors from any execution context, including their stack traces, which can be sent to a server for logging.
Capturing Stack Information
Example of sending stack data to a server:
window.addEventListener('error', function (e) {
var stack = e.error.stack;
var message = e.error.toString();
if (stack) {
message += '
' + stack;
}
var xhr = new XMLHttpRequest();
xhr.open('POST', '/log', true);
xhr.send(message);
});Asynchronous Handling
Try‑catch cannot catch errors inside asynchronous callbacks; promises or explicit try‑catch inside the callback are needed:
function asyncHandler(fn) {
try {
setTimeout(function () {
fn();
}, 1);
} catch (e) { }
}Unit test demonstrates that the error must be captured via a rejected promise.
Conclusion
Silent‑failure handling hides problems and makes debugging hard, while proper use of try‑catch, global onerror, and promise‑based error propagation leads to clearer, maintainable code and easier error reporting.
Translator’s note: Effective error handling improves front‑end code quality; combining global onerror with strategic try‑catch is recommended.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Tencent IMWeb Frontend Team
IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
