try…catch…finally code to be put into try block if no errors, then catch block is ignored if an error the script is not killed try...catch works synchronously, no delayed functions will be executed if an error occurs, then execution in try block is stopped try...catch can only handle errors that occur in valid code catch block has default error variable which contains an error object finally block always executes finally can be omitted try { alert('Start of try runs') lalala // error, variable is not defined! alert('End of try (never reached)') } catch(err) { alert(`Error has occurred!`) console.dir(err) } finally { alert('bugs happens, do not get upset') } Finally and return be careful with return statement in try & finally blocks return value in finally block overwrites a value in try block function example() { try { return true; } finally { console.log('finally') return false } } // finally // false Scheduled function setTimeout(function() { try { noSuchVariable // try...catch handles the error! } catch (err) { alert( "error is caught here!" ) } }, 1000) Error object try { lalala; // error, variable is not defined! } catch (err) { alert(err.name); // ReferenceError alert(err.message); // lalala is not defined alert(err.stack); // ReferenceError: lalala is not defined at (...call stack) // Can also show an error as a whole // The error is converted to string as "name: message" alert(err); // ReferenceError: lalala is not defined } Different ways to create error object let error = new Error(message) let error = new SyntaxError(message) let error = new ReferenceError(message) let error = new TypeError(message) Or even extend built-in class (overkill!!!) class ValidationError extends Error { constructor(message) { super(message) this.name = "ValidationError" } } // Usage function readUser(json) { let user = JSON.parse(json) if (!user.age) throw new ValidationError("No field: age") if (!user.name) throw new ValidationError("No field: name") return user } // Working example with try..catch try { let user = readUser('{ "age": 25 }') } catch (err) { if (err instanceof ValidationError) { alert("Invalid data: " + err.message) // Invalid data: No field: name } else if (err instanceof SyntaxError) { // (*) alert("JSON Syntax Error: " + err.message) } else { throw err // unknown error, rethrow it (**) } } Throw own error let error = new Error("Things happen o_O") error.name // Error error.message // Things happen o_O let json = '{ "age": 30 }' // incomplete data try { let user = JSON.parse(json) // <-- no errors if (!user.name) { // generate error object throw new SyntaxError("no name!") } // never come here alert(user.name) } catch (err) { console.dir(err) // JSON Error: Incomplete data: no name Re -throw error function readData() { let json = '{ "age": 30 }'; try { blabla(); // error! } catch (err) { if (!(err instanceof SyntaxError)) { throw err; // rethrow (don't know how to deal with it) } } } try { readData(); } catch (err) { alert( "External catch got: " + err ); // caught it! } Finally always executes even if we use return in try block can use it if don’t want to handle errors, but want to finalize process function func() { try { console.log('try') return } catch (err) { } finally { console.log('finally' ) } } func() // try // finally Global catch error listener In case of fatal error outside try...catch ErrorEvent contains all the information about the event and the error. window.addEventListener('error', function(event) { alert(event.message) // human-readable error message describing the problem. console.log(event.filename) // name of the script file in which the error occurred. console.log(event.lineno ) // line number of the script file on which the error occurred. console.log(event.colno) // column number of the script file on which the error occurred. console.log(event.error) // Is a JavaScript Object that is concerned by the event. })