Error Handling
## Learning Objectives
- Understand JavaScript error types
- Master try/catch/finally
- Create custom error classes
- Implement global error handling
## Error Types
### SyntaxError
```javascript
// JSON.parse("invalid json"); // SyntaxError
const x = ; // SyntaxError
```
### TypeError
```javascript
const obj = null;
obj.property; // TypeError: Cannot read property of null
const fn = undefined;
fn(); // TypeError: fn is not a function
```
### ReferenceError
```javascript
console.log(undefinedVar); // ReferenceError: undefinedVar is not defined
```
### RangeError
```javascript
const arr = new Array(-1); // RangeError: Invalid array length
```
### URIError
```javascript
decodeURIComponent("%2"); // URIError: URI malformed
```
## try/catch/finally
```javascript
try {
// Code that might throw
const data = JSON.parse(userInput);
console.log(data);
} catch (error) {
// Handle the error
console.error("Invalid JSON:", error.message);
} finally {
// Always executes
console.log("Cleanup here");
}
```
## The Error Object
```javascript
try {
throw new Error("Something went wrong");
} catch (error) {
console.log(error.name); // "Error"
console.log(error.message); // "Something went wrong"
console.log(error.stack); // Stack trace
}
```
## Throwing Errors
```javascript
// Throw primitive (not recommended)
throw "Error string";
throw 42;
// Throw Error object (recommended)
throw new Error("Error message");
throw new TypeError("Expected string");
throw new RangeError("Number out of range");
```
## Custom Error Classes
```javascript
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
class NotFoundError extends Error {
constructor(resource) {
super(`${resource} not found`);
this.name = "NotFoundError";
this.resource = resource;
}
}
// Usage
function findUser(id) {
const user = database.find(id);
if (!user) {
throw new NotFoundError("User");
}
return user;
}
```
## Async Error Handling
### With Promises
```javascript
fetch("/api/data")
.then(response => {
if (!response.ok) {
throw new Error("HTTP error!");
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error("Failed:", error));
```
### With async/await
```javascript
async function fetchData() {
try {
const response = await fetch("/api/data");
if (!response.ok) {
throw new Error("HTTP error!");
}
const data = await response.json();
return data;
} catch (error) {
console.error("Failed:", error);
throw error; // Re-throw if needed
}
}
```
## finally with async
```javascript
async function processFile(file) {
let fileHandle;
try {
fileHandle = await fs.open(file);
const data = await fileHandle.read();
return data;
} catch (error) {
console.error("Error:", error);
} finally {
if (fileHandle) {
await fileHandle.close();
}
}
}
```
## Global Error Handling
### Browser
```javascript
window.addEventListener("error", (event) => {
console.error("Global error:", event.error);
});
window.addEventListener("unhandledrejection", (event) => {
console.error("Unhandled rejection:", event.reason);
});
```
### Node.js
```javascript
process.on("uncaughtException", (error) => {
console.error("Uncaught Exception:", error);
});
process.on("unhandledRejection", (reason, promise) => {
console.error("Unhandled Rejection at:", promise, "reason:", reason);
});
```
## Error Handling Patterns
### Optional Chaining for Error Prevention
```javascript
// Instead of
if (user && user.address && user.address.city) {
console.log(user.address.city);
}
// Use
console.log(user?.address?.city);
```
### nullish Coalescing for Defaults
```javascript
const name = user?.name ?? "Anonymous";
```
### Graceful Degradation
```javascript
try {
const result = riskyOperation();
displayResult(result);
} catch {
displayFallback(); // Show something else
}
```
## Summary
- Use `try/catch/finally` for synchronous error handling
- Always handle async errors with `.catch()` or try/catch in async functions
- Create custom error classes for specific error types
- Use `finally` for cleanup code that must run
- Set up global error handlers for uncaught exceptions
- Never swallow errors silently - at minimum, log them
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →