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.
})