Error Handling
Errors are not signs of failure — they are signals. Learn everything from basic try/catch to advanced real-world error architectures used in production apps.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
💡 Running Code Locally: While this online editor runs real JavaScript, some advanced examples may have limitations. For the best experience:
JavaScript gives you extremely powerful tools to handle, detect, filter, categorize, and recover from errors — synchronously AND asynchronously.
An error occurs when JavaScript cannot complete an operation. Examples:
By default, errors stop execution. Your job is to catch, interpret, and recover from them.
JavaScript allows you to create and throw your own errors:
This lets you create fine-grained error logic.
Sometimes you want to catch an error, log it, then pass it upward:
Now your UI doesn't crash when the API fails — it gracefully recovers.
Asynchronous code is where 90% of real production errors happen.
You MUST master async error strategies to build real-world websites, apps, and SaaS systems.
⚠️ It does NOT throw errors for bad HTTP codes (404, 500, 403, 429)
Without this check, your code will behave like everything is fine when it absolutely isn't.
Real-world apps must recover from errors gracefully:
Retries at: 200ms → 400ms → 600ms. This is used by Google, AWS, Netflix, Stripe, PayPal.
Defensive programming = writing code that assumes things will go wrong.
Most frameworks implement a global error handler:
You will encounter these daily in real development.
Build a function: safeFetch(url, retries = 3)
You've mastered the art of writing robust code that handles failure gracefully. This separates amateur code from professional software.
Up next: Closures & Scope — diving deep into advanced JavaScript concepts! 🧠
Practice quiz
In a try/catch/finally block, when does the finally block run?
- Only when an error is thrown
- Only when no error is thrown
- Always, regardless of the outcome
- Never, it is optional
Answer: Always, regardless of the outcome. finally always runs, making it ideal for cleanup like closing connections or removing loaders.
Which keyword do you use to manually trigger an error?
- throw
- raise
- error
- catch
Answer: throw. throw manually triggers an error, for example throw new Error('Cannot divide by zero').
Which error type is thrown by null.toUpperCase()?
- ReferenceError
- SyntaxError
- RangeError
- TypeError
Answer: TypeError. Calling a method on null is an incorrect data type operation, which throws a TypeError.
Which error type occurs when you use a variable that was never declared?
- TypeError
- ReferenceError
- RangeError
- URIError
Answer: ReferenceError. Referencing an undeclared variable throws a ReferenceError.
How do you create a custom error class?
- class MyError extends Error { }
- function MyError()
- new CustomError()
- Error.create('My')
Answer: class MyError extends Error { }. Custom errors extend the built-in Error class, e.g. class ValidationError extends Error.
Does fetch() throw an error for HTTP status codes like 404 or 500?
- Yes, always
- Only for 500
- No, you must check res.ok yourself
- Only in strict mode
Answer: No, you must check res.ok yourself. fetch only rejects for network-level failures; you must check res.ok for bad HTTP status codes.
What does 're-throwing' an error mean?
- Catching an error and ignoring it
- Catching an error, handling it locally, then throwing it again to pass it upward
- Throwing two errors at once
- Converting an error to a string
Answer: Catching an error, handling it locally, then throwing it again to pass it upward. Re-throwing lets you log or add context locally, then pass the error up with throw err.
How can you handle errors in async/await code?
- With a .then() only
- Errors cannot be caught in async code
- With window.onerror only
- By wrapping the awaited calls in try/catch
Answer: By wrapping the awaited calls in try/catch. async/await uses ordinary try/catch around the awaited operations to catch failures.
In an outer/inner nested try/catch, where is an error thrown in the inner try caught first?
- The outer catch
- The inner catch
- Both simultaneously
- Neither
Answer: The inner catch. The nearest enclosing catch handles it first; the inner catch catches the inner error.
Which is a recommended error-handling best practice from the lesson?
- Show database stack traces to users
- Ignore async errors
- Use specific error messages and don't leak sensitive info
- Fail silently
Answer: Use specific error messages and don't leak sensitive info. Use clear, specific messages, handle async errors, and never leak sensitive details to users.