Bird
Raised Fist0
Node.jsframework~20 mins

Error-first callback convention in Node.js - Practice Problems & Coding Challenges

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
Challenge - 5 Problems
🎖️
Error-first Callback Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
Understanding error-first callback output
What will be the output of this Node.js code using an error-first callback?
Node.js
function fetchData(callback) {
  setTimeout(() => {
    callback(null, 'Data loaded');
  }, 100);
}

fetchData((err, data) => {
  if (err) {
    console.log('Error:', err);
  } else {
    console.log('Success:', data);
  }
});
AError: null
BSuccess: null
CSuccess: Data loaded
DError: Data loaded
Attempts:
2 left
💡 Hint
Remember, the first argument is the error, the second is the data.
Predict Output
intermediate
2:00remaining
Detecting error in error-first callback
What will this code print when the callback receives an error?
Node.js
function readFile(callback) {
  setTimeout(() => {
    callback(new Error('File not found'), null);
  }, 50);
}

readFile((err, content) => {
  if (err) {
    console.log('Error:', err.message);
  } else {
    console.log('Content:', content);
  }
});
AContent: File not found
BContent: null
CError: null
DError: File not found
Attempts:
2 left
💡 Hint
Check how the error object is passed and accessed.
component_behavior
advanced
2:30remaining
Behavior of nested error-first callbacks
Consider this nested callback code. What will be logged?
Node.js
function step1(cb) {
  setTimeout(() => cb(null, 'Step1 done'), 30);
}
function step2(cb) {
  setTimeout(() => cb(new Error('Step2 failed'), null), 20);
}

step1((err, res1) => {
  if (err) {
    console.log('Error in step1:', err.message);
  } else {
    step2((err, res2) => {
      if (err) {
        console.log('Error in step2:', err.message);
      } else {
        console.log('Success:', res2);
      }
    });
  }
});
AError in step1: Step2 failed
BError in step2: Step2 failed
CSuccess: Step2 failed
DSuccess: Step1 done
Attempts:
2 left
💡 Hint
Look carefully at which callback receives the error.
📝 Syntax
advanced
2:00remaining
Identify the syntax error in error-first callback usage
Which option contains a syntax error in the error-first callback pattern?
Node.js
function getData(callback) {
  setTimeout(() => {
    callback(null, 'OK');
  }, 10);
}

getData((err data) => {
  if (err) {
    console.log('Error:', err);
  } else {
    console.log('Data:', data);
  }
});
AgetData((err data) => { console.log(data); });
BgetData((err, data) => { console.log(data); });
CgetData(function(err, data) { console.log(data); });
DgetData((error, result) => { console.log(result); });
Attempts:
2 left
💡 Hint
Check the arrow function parameter list syntax.
🔧 Debug
expert
3:00remaining
Debugging incorrect error handling in callback
What is the main problem with this error-first callback usage?
Node.js
function processData(callback) {
  setTimeout(() => {
    callback(null, 'Done');
  }, 10);
}

processData((err, data) => {
  if (!err) {
    console.log('Error:', err.message);
  } else {
    console.log('Success:', data);
  }
});
AIt logs 'Error: Cannot read property message of null' because err is null but accessed as an object.
BIt logs 'Success: Done' correctly.
CIt throws a syntax error due to wrong if condition.
DIt never logs anything because callback is not called.
Attempts:
2 left
💡 Hint
Check how err is tested and used inside the callback.

Practice

(1/5)
1. What is the main purpose of the error-first callback convention in Node.js?
easy
A. To avoid using callbacks and use promises instead
B. To pass the result as the first argument and error as the second
C. To handle errors only after all callbacks have finished
D. To always pass the error as the first argument to the callback function

Solution

  1. Step 1: Understand the callback argument order

    The error-first callback convention means the first argument is always the error if any occurred.
  2. Step 2: Recognize the purpose of this order

    This helps developers check for errors before processing results, making code safer and clearer.
  3. Final Answer:

    To always pass the error as the first argument to the callback function -> Option D
  4. Quick Check:

    Error is first argument [OK]
Hint: Error always comes first in callbacks [OK]
Common Mistakes:
  • Thinking result comes before error
  • Confusing error-first with promise usage
  • Ignoring error handling in callbacks
2. Which of the following is the correct syntax for an error-first callback function in Node.js?
easy
A. function callback(error, result) { ... }
B. function callback(result, error) { ... }
C. function callback() { ... }
D. function callback(result) { ... }

Solution

  1. Step 1: Identify the correct parameter order

    The error-first callback convention requires the first parameter to be error, second to be result.
  2. Step 2: Match the syntax

    Only the function with parameters (error, result) follows this convention correctly.
  3. Final Answer:

    function callback(error, result) { ... } -> Option A
  4. Quick Check:

    Callback params: error first, result second [OK]
Hint: Error is first parameter in callback functions [OK]
Common Mistakes:
  • Swapping error and result parameters
  • Omitting error parameter
  • Using only one parameter for result
3. Consider the following code snippet:
function readFile(callback) {
  setTimeout(() => {
    callback(null, 'file content');
  }, 100);
}

readFile((err, data) => {
  if (err) {
    console.log('Error:', err);
  } else {
    console.log('Data:', data);
  }
});

What will be printed to the console?
medium
A. Error: null
B. Data: file content
C. Error: file content
D. Nothing will be printed

Solution

  1. Step 1: Analyze the callback invocation

    The callback is called with null as error and 'file content' as data after 100ms.
  2. Step 2: Check the callback logic

    Since err is null (no error), the else branch runs and logs 'Data: file content'.
  3. Final Answer:

    Data: file content -> Option B
  4. Quick Check:

    Null error means success, so data logs [OK]
Hint: Null error means no error, print data [OK]
Common Mistakes:
  • Printing error when error is null
  • Confusing error and data values
  • Expecting no output due to async
4. Identify the error in this code using error-first callback convention:
function getData(callback) {
  const error = null;
  const result = 'Success';
  callback(result, error);
}

getData((err, data) => {
  if (err) {
    console.log('Error:', err);
  } else {
    console.log('Data:', data);
  }
});
medium
A. No error handling is needed here
B. The callback function is missing
C. The callback arguments are reversed; error should be first
D. The error variable should be a string, not null

Solution

  1. Step 1: Check callback argument order

    The callback is called with (result, error) but error-first convention requires (error, result).
  2. Step 2: Understand impact of reversed arguments

    This reversal causes the callback to treat 'Success' as error and null as data, breaking logic.
  3. Final Answer:

    The callback arguments are reversed; error should be first -> Option C
  4. Quick Check:

    Callback args must be (error, result) [OK]
Hint: Error must be first argument in callback calls [OK]
Common Mistakes:
  • Passing result before error
  • Ignoring argument order in callbacks
  • Assuming error can be second argument
5. You have a function that reads user data asynchronously and uses an error-first callback:
function fetchUser(id, callback) {
  if (id <= 0) {
    callback(new Error('Invalid ID'), null);
  } else {
    setTimeout(() => {
      callback(null, { id, name: 'Alice' });
    }, 50);
  }
}

How should you call fetchUser to correctly handle errors and print the user's name or the error message?
hard
A. fetchUser(1, (err, user) => { if (err) console.log(err.message); else console.log(user.name); });
B. fetchUser(1, (err, user) => { if (user) console.log(user.name); else console.log(err.message); });
C. fetchUser(1, (user, err) => { if (err) console.log(err.message); else console.log(user.name); });
D. fetchUser(1, (err, user) => { console.log(user.name); });

Solution

  1. Step 1: Check callback parameter order and error handling

    The callback parameters must be (err, user). We check if err exists first to handle errors.
  2. Step 2: Verify correct conditional logic

    If err exists, print err.message; otherwise, print user.name. fetchUser(1, (err, user) => { if (err) console.log(err.message); else console.log(user.name); }); follows this correctly.
  3. Final Answer:

    fetchUser(1, (err, user) => { if (err) console.log(err.message); else console.log(user.name); }); -> Option A
  4. Quick Check:

    Check error first, then use user [OK]
Hint: Always check error before using result in callback [OK]
Common Mistakes:
  • Swapping error and user parameters
  • Not checking error before accessing user
  • Ignoring error handling completely