🏠 Home / Hub
🟨 JS Lesson 14 — Error Handling
← Back to JS Menu | 🏠 Hub
1. Error Types
| Error Type | When It Happens | Example |
| SyntaxError | Code parsing — run ပင် မလုပ်ရ | let x = ; (missing value) |
| ReferenceError | Undefined variable use | console.log(undeclared) |
| TypeError | Wrong type operation | null.toString() |
| RangeError | Number out of range | new Array(-1) |
| URIError | Bad URI encoding | decodeURIComponent('%') |
| Custom Error | App-specific errors | throw new ValidationError() |
// Error object properties
try {
null.toString();
} catch (e) {
e.name; // "TypeError"
e.message; // "Cannot read properties of null"
e.stack; // full stack trace (multi-line string)
}
2. try / catch / finally
// Basic try/catch
function divide(a, b) {
try {
if (b === 0) throw new Error("Cannot divide by zero");
return a / b;
} catch (err) {
console.error("Error:", err.message);
return null;
} finally {
console.log("divide() called"); // ALWAYS runs
}
}
divide(10, 2); // 5, logs "divide() called"
divide(10, 0); // null, logs error + "divide() called"
// Catch specific error types
function parseJSON(str) {
try {
return JSON.parse(str);
} catch (e) {
if (e instanceof SyntaxError) {
return { error: "Invalid JSON format" };
}
throw e; // re-throw unexpected errors
}
}
parseJSON('{"name":"Ko"}'); // { name: "Ko" }
parseJSON('not json'); // { error: "Invalid JSON format" }
3. Custom Error Classes
// Custom errors — descriptive, catchable
class AppError extends Error {
constructor(message, statusCode = 500) {
super(message);
this.name = "AppError";
this.statusCode = statusCode;
}
}
class ValidationError extends AppError {
constructor(message, field) {
super(message, 400);
this.name = "ValidationError";
this.field = field;
}
}
class NotFoundError extends AppError {
constructor(resource) {
super(`${resource} not found`, 404);
this.name = "NotFoundError";
}
}
class AuthError extends AppError {
constructor(message = "Unauthorized") {
super(message, 401);
this.name = "AuthError";
}
}
// Using custom errors
function getUser(id) {
if (typeof id !== "number") throw new ValidationError("id must be a number", "id");
if (id <= 0) throw new ValidationError("id must be positive", "id");
if (id > 1000) throw new NotFoundError("User");
return { id, name: "Ko Ko" };
}
try {
getUser("abc");
} catch (e) {
if (e instanceof ValidationError) {
console.log(`Validation failed on field '${e.field}': ${e.message}`);
} else if (e instanceof NotFoundError) {
console.log(`404: ${e.message}`);
} else if (e instanceof AppError) {
console.log(`App error ${e.statusCode}: ${e.message}`);
} else {
throw e; // unexpected — let it bubble up
}
}
4. Async Error Handling
// async/await error handling
async function fetchUser(id) {
try {
const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
if (!res.ok) {
throw new AppError(`HTTP ${res.status}`, res.status);
}
const data = await res.json();
return data;
} catch (e) {
if (e instanceof TypeError) {
// Network error (no internet, CORS, etc.)
throw new AppError("Network error — check connection");
}
throw e; // re-throw AppError or others
}
}
// Safe wrapper pattern
async function safeCall(fn, ...args) {
try {
const data = await fn(...args);
return { data, error: null };
} catch (error) {
return { data: null, error: error.message };
}
}
// Usage
const { data, error } = await safeCall(fetchUser, 1);
if (error) {
console.log("Failed:", error);
} else {
console.log("User:", data.name);
}
5. Global Error Handlers
// Catch unhandled errors globally (browser)
window.addEventListener("error", (event) => {
console.error("Unhandled error:", event.error);
// Send to logging service (Sentry, etc.)
});
window.addEventListener("unhandledrejection", (event) => {
console.error("Unhandled Promise rejection:", event.reason);
event.preventDefault(); // prevent console error
});
// Node.js global handlers
process.on("uncaughtException", (err) => {
console.error("Uncaught Exception:", err);
process.exit(1); // clean exit
});
process.on("unhandledRejection", (reason, promise) => {
console.error("Unhandled Rejection:", reason);
process.exit(1);
});
// Error Boundary pattern (functional)
function withErrorBoundary(fn, fallback) {
return function(...args) {
try {
return fn(...args);
} catch (e) {
console.error(e);
return fallback;
}
};
}
const safeParseInt = withErrorBoundary(
(s) => { if (isNaN(s)) throw new Error("Not a number"); return parseInt(s); },
0 // fallback
);
safeParseInt("42"); // 42
safeParseInt("abc"); // 0 (fallback)
🎉 JavaScript Complete!
Variables → Conditions → Loops → Functions → Arrays → Objects → DOM → Events → OOP Classes → Inheritance → Prototype → Closures → Design Patterns → Error Handling
🏠 Hub
🟨 JS Menu
← JS 13 |
🏠 Back to Hub
📌 Study Checklist
- အပေါ်က concept ကို တစ်ကြောင်းချင်းဖတ်ပြီး example ကို ကိုယ်တိုင်ပြန်ရေးကြည့်ပါ။
- Code/command ပါတဲ့ lesson ဆိုရင် value/name/path တစ်ခုခု ပြောင်းပြီး result ဘာကွာလဲ စမ်းပါ။
- မမှတ်မိသေးတဲ့ keyword 3 ခုကို notebook ထဲရေးပြီး နောက် lesson မသွားခင် ပြန်ရှင်းကြည့်ပါ။
- ပြီးရင် Home / Hub ကိုပြန်သွားပြီး next lesson ဆက်သင်ပါ။