Bird
Raised Fist0
Node.jsframework~10 mins

Error handling in async/await in Node.js - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Error handling in async/await
Start async function
Try block: await async call
Async call success?
NoCatch block: handle error
Error handled/logged
Continue normal flow
End
This flow shows how async/await uses try/catch to handle errors from asynchronous calls, allowing normal flow if no error occurs or error handling if one happens.
Execution Sample
Node.js
async function fetchData() {
  try {
    const data = await fetch('https://api.example.com/data');
    return await data.json();
  } catch (error) {
    console.error('Fetch error:', error);
  }
}
This code tries to fetch data asynchronously and catches any error that happens during the fetch or JSON parsing.
Execution Table
StepActionEvaluationResult
1Call fetchData()Enter async functionStart try block
2await fetch('https://api.example.com/data')Fetch request sentPromise pending
3Fetch resolves successfullyResponse receivedResponse object stored in data
4await data.json()Parse JSONParsed JSON returned
5Return parsed JSONFunction resolvesData returned to caller
6Function endsNo error thrownNormal completion
💡 Function ends normally because no error occurred during fetch or JSON parsing
Variable Tracker
VariableStartAfter Step 3After Step 4Final
dataundefinedResponse objectResponse objectResponse object
Key Moments - 2 Insights
Why do we use try/catch with async/await?
Because await pauses the function until the promise settles, errors thrown inside await calls must be caught with try/catch to avoid unhandled rejections, as shown in steps 2-5 of the execution_table.
What happens if fetch fails?
If fetch fails, the promise rejects and control jumps to the catch block (not shown in this successful run), where the error can be handled or logged, preventing the function from crashing.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'data' after step 3?
Aundefined
BParsed JSON object
CResponse object
DError object
💡 Hint
Check variable_tracker column 'After Step 3' for 'data'
At which step does the function return the parsed JSON data?
AStep 3
BStep 5
CStep 4
DStep 6
💡 Hint
Look at execution_table row where 'Return parsed JSON' happens
If fetch fails, which part of the flow handles the error?
ACatch block handles the error
BTry block continues normally
CFunction returns undefined immediately
DError is ignored
💡 Hint
Refer to concept_flow where 'No' branch from async call success leads to catch block
Concept Snapshot
async/await error handling:
- Use try { await asyncCall() } catch (error) { handle error }
- Await pauses until promise settles
- Errors thrown inside await go to catch
- Prevents unhandled promise rejections
- Keeps async code readable and safe
Full Transcript
This visual execution shows how error handling works with async/await in Node.js. The async function starts and enters a try block where it awaits a fetch call. If the fetch succeeds, it proceeds to parse JSON and returns the data. If any error occurs during fetch or parsing, control jumps to the catch block where the error is handled or logged. Variables like 'data' change from undefined to response object to parsed JSON. This pattern ensures asynchronous errors are caught cleanly, avoiding crashes or unhandled rejections.

Practice

(1/5)
1. What is the main purpose of using try/catch blocks with async/await in Node.js?
easy
A. To catch and handle errors from asynchronous operations
B. To speed up the execution of async functions
C. To convert async functions into synchronous ones
D. To automatically retry failed async operations

Solution

  1. Step 1: Understand async/await behavior

    Async functions return promises and can throw errors when awaited operations fail.
  2. Step 2: Role of try/catch

    Try/catch blocks catch these errors to prevent crashes and allow handling.
  3. Final Answer:

    To catch and handle errors from asynchronous operations -> Option A
  4. Quick Check:

    Error handling = A [OK]
Hint: Use try/catch around await to catch errors [OK]
Common Mistakes:
  • Thinking async/await automatically handles errors
  • Using try/catch outside async functions only
  • Ignoring errors causing app crashes
2. Which of the following is the correct syntax to handle errors in an async function using async/await?
easy
A. async function fetchData() { try { await fetch(url); } catch (err) { console.error(err); } }
B. async function fetchData() { await fetch(url); }
C. async function fetchData() { try { fetch(url); } catch (err) { console.error(err); } }
D. async function fetchData() { await fetch(url).catch(console.error); }

Solution

  1. Step 1: Check proper use of try/catch with await

    async function fetchData() { try { await fetch(url); } catch (err) { console.error(err); } } correctly wraps the await call inside try and catches errors.
  2. Step 2: Identify incorrect patterns

    async function fetchData() { await fetch(url).catch(console.error); } uses .catch on await which is invalid syntax; async function fetchData() { try { fetch(url); } catch (err) { console.error(err); } } misses await; async function fetchData() { await fetch(url); } has no error handling.
  3. Final Answer:

    async function fetchData() { try { await fetch(url); } catch (err) { console.error(err); } } -> Option A
  4. Quick Check:

    Try/catch with await = D [OK]
Hint: Put await inside try block to catch errors [OK]
Common Mistakes:
  • Using .catch() directly on await expression
  • Forgetting to use await inside try
  • Not catching errors at all
3. Consider this code snippet:
async function getData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    return data;
  } catch (error) {
    return 'Error occurred';
  }
}

getData().then(console.log);

What will be logged if the fetch fails due to network error?
medium
A. An unhandled promise rejection error
B. The raw error object
C. Undefined
D. 'Error occurred'

Solution

  1. Step 1: Analyze try/catch behavior on fetch failure

    If fetch fails, control jumps to catch block which returns 'Error occurred'.
  2. Step 2: Understand promise resolution

    getData returns a resolved promise with string 'Error occurred', so console.log prints that string.
  3. Final Answer:

    'Error occurred' -> Option D
  4. Quick Check:

    Catch returns string on error = B [OK]
Hint: Catch block return value is logged on error [OK]
Common Mistakes:
  • Expecting unhandled error instead of caught return
  • Confusing error object with returned string
  • Ignoring async function returns promise
4. Identify the error in this async function:
async function loadUser() {
  try {
    const user = fetch('https://api.example.com/user');
    console.log(user.name);
  } catch (err) {
    console.error(err);
  }
}
medium
A. Incorrect catch block syntax
B. Missing await before fetch causing user to be a Promise
C. console.log should be inside catch block
D. fetch URL is invalid

Solution

  1. Step 1: Check fetch usage

    fetch returns a Promise; without await, user is a Promise object, not the resolved data.
  2. Step 2: Consequence of missing await

    Accessing user.name fails because user is not the actual data but a Promise.
  3. Final Answer:

    Missing await before fetch causing user to be a Promise -> Option B
  4. Quick Check:

    Await missing = A [OK]
Hint: Always await fetch to get resolved data before use [OK]
Common Mistakes:
  • Forgetting await before async calls
  • Assuming fetch returns data directly
  • Misplacing console.log outside async flow
5. You want to fetch user data and then fetch posts by that user. Both calls can fail. How should you handle errors to ensure you catch failures in either step and log a clear message?
async function getUserPosts(userId) {
  // Your code here
}
hard
A. Use nested try/catch blocks: one for user fetch, one for posts fetch
B. Use .then().catch() chaining instead of async/await
C. Use a single try/catch wrapping both awaits for user and posts fetch
D. Ignore errors and let them crash the app

Solution

  1. Step 1: Understand error flow in async/await

    A single try/catch can catch errors from any awaited call inside it.
  2. Step 2: Simplify error handling

    Wrapping both awaits in one try/catch logs errors clearly without nesting complexity.
  3. Final Answer:

    Use a single try/catch wrapping both awaits for user and posts fetch -> Option C
  4. Quick Check:

    One try/catch covers multiple awaits = C [OK]
Hint: Wrap all awaits in one try/catch for simple error handling [OK]
Common Mistakes:
  • Overcomplicating with nested try/catch
  • Using .then().catch() mixing styles
  • Not handling errors causing silent failures