ES6 - Error Handling
ES6 - Error Handling
Section titled “ES6 - Error Handling”Error handling is a critical aspect of writing robust JavaScript applications. It involves anticipating, detecting, and responding to errors that may occur during program execution.
Types of Errors
Section titled “Types of Errors”- Syntax Errors: Occur when code violates the grammatical rules of JavaScript. These are detected by the JavaScript engine during parsing (before execution) and prevent the script (or module) from running. Example: a missing parenthesis.
- Runtime Errors (Exceptions): Occur during the execution of the code. These happen when the engine encounters an operation it cannot perform. Examples: trying to call a method on an
undefinedvariable, dividing by zero (though JS returnsInfinity), or referencing an undeclared variable (in strict mode). - Logical Errors: The code runs without throwing syntax or runtime errors, but it doesn’t produce the intended result due to flaws in the program’s logic. These are often the hardest to debug as the engine doesn’t report them as errors.
The try...catch...finally Statement
Section titled “The try...catch...finally Statement”This is the primary mechanism for handling runtime errors (exceptions) in synchronous JavaScript code.
tryblock: Contains the code that might throw an exception.catch (error)block: If an exception occurs within thetryblock, control is transferred to thecatchblock. Theerrorobject (or whatever name you give the parameter) contains information about the error.finallyblock (optional): Contains code that will execute after thetryandcatchblocks, regardless of whether an exception was thrown or caught. It’s often used for cleanup operations (e.g., closing resources).
Syntax:
Section titled “Syntax:”try { // Code that might throw an error} catch (error) { // Code to handle the error // 'error' is an Error object} finally { // Code that always executes}Example: try...catch
Section titled “Example: try...catch”function divide(a, b) { try { if (b === 0) { throw new Error("Division by zero is not allowed."); } const result = a / b; console.log(`Result: ${result}`); return result; } catch (error) { console.error(`Error Name: ${error.name}`); console.error(`Error Message: ${error.message}`); // console.error(`Stack Trace: ${error.stack}`); // Useful for debugging return null; // Or handle differently } finally { console.log("Division attempt finished."); }}
divide(10, 2); // Result: 5, Division attempt finished.divide(10, 0); // Error messages, Division attempt finished.The Error Object
Section titled “The Error Object”When a runtime error occurs, JavaScript creates and throws an Error object (or an instance of one of its subtypes). Key properties of an Error object include:
name: The type of error (e.g.,"Error","TypeError","ReferenceError").message: A human-readable description of the error.stack(non-standard but widely supported): A string containing the call stack trace, useful for debugging.
Standard Built-in Error Types:
Section titled “Standard Built-in Error Types:”| Sr.No | Error Type | Description |
|---|---|---|
| 1 | Error | Generic base error object. |
| 2 | EvalError | Represents an error regarding the global eval() function. Rarely thrown in modern JavaScript; other errors are more common. |
| 3 | RangeError | Indicates a numeric variable or parameter is outside of its valid range. (e.g., new Array(-1)) |
| 4 | ReferenceError | Occurs when trying to access a variable that hasn’t been declared (in strict mode) or is out of scope. |
| 5 | SyntaxError | Indicates a parsing error in the code. These usually prevent execution and are not catchable by try...catch unless eval() or similar is used. |
| 6 | TypeError | Occurs when an operation cannot be performed, typically when a value is not of the expected type (e.g., calling a method on null or undefined, or treating a non-function as a function). |
| 7 | URIError | Indicates that encodeURI(), decodeURI(), encodeURIComponent(), or decodeURIComponent() were passed invalid parameters. |
The throw Statement
Section titled “The throw Statement”You can create and throw your own exceptions using the throw statement. You can throw any expression, but it’s best practice to throw an Error object or an instance of a custom error class derived from Error.
Syntax: throw new ErrorType("Descriptive message");
Example: Throwing an error
Section titled “Example: Throwing an error”function validateAge(age) { if (typeof age !== 'number') { throw new TypeError("Age must be a number."); } if (age < 0) { throw new RangeError("Age cannot be negative."); } console.log("Age is valid.");}
try { validateAge(-5);} catch (e) { console.error(`${e.name}: ${e.message}`); // RangeError: Age cannot be negative.}Creating Custom Errors
Section titled “Creating Custom Errors”For more specific error handling, you can create custom error classes by extending the built-in Error class.
Example: Custom Error Class
Section titled “Example: Custom Error Class”class NetworkError extends Error { constructor(message, statusCode) { super(message); // Call the parent constructor (Error) this.name = "NetworkError"; this.statusCode = statusCode; }}
try { // Simulate a network issue throw new NetworkError("Failed to connect to the server.", 503);} catch (e) { if (e instanceof NetworkError) { console.error(`Custom Error (${e.name}): ${e.message}, Status: ${e.statusCode}`); } else { console.error(`Generic Error: ${e.message}`); }}Asynchronous Error Handling
Section titled “Asynchronous Error Handling”try...catch only works for synchronous code. For asynchronous operations like those involving Promises or setTimeout:
- Promises: Use the
.catch(errorHandler)method or the second callback in.then(successHandler, errorHandler). async/await: You can usetry...catcharoundawaitexpressions to handle rejections from awaited promises.- Callbacks: Error handling typically involves an error-first callback convention (e.g.,
callback(error, data)).
Example: Async/Await with try…catch
Section titled “Example: Async/Await with try…catch”async function fetchData() { try { const response = await fetch('https://api.example.com/data'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error("Failed to fetch data:", error); // Handle or re-throw }}fetchData();window.onerror and window.onunhandledrejection
Section titled “window.onerror and window.onunhandledrejection”-
window.onerror = function(message, source, lineno, colno, error): A global event handler for uncaught synchronous errors that occur in scripts loaded by the window. It’s a last resort for error logging or reporting. -
window.onunhandledrejection = function(event): A global event handler for uncaught promise rejections. Theevent.reasonproperty contains the rejection value.
These global handlers are useful for telemetry and global error tracking but shouldn’t replace specific try...catch blocks or Promise .catch() handlers for application logic.
For more on error handling: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling