JavaScript Error Handling (try, catch, finally) Quiz

JavaScript
0 Passed
0% acceptance

Tackle 40 questions on why try/catch exists, how to structure catch/finally blocks, inspecting error objects, throwing custom errors, handling specific cases, nesting handlers, and modern best practices.

40 Questions
~80 minutes
1

Question 1

What is the primary reason to use try/catch?

A
Prevent unhandled runtime errors from crashing the application abruptly
B
Improve performance of loops
C
Replace if statements
D
Handle compile-time syntax errors
2

Question 2

Which block executes only when an exception is thrown inside try?

A
catch
B
finally
C
throw
D
else
3

Question 3

Which statement about finally is correct?

A
finally runs after try/catch regardless of whether an error occurred
B
finally runs only when catch executes
C
finally must appear before catch
D
finally prevents errors from bubbling
4

Question 4

Can a try block exist without a catch block?

A
Yes, as long as it has a finally block
B
No, catch is mandatory
C
Yes, but only in strict mode
D
Yes, but only with async functions
5

Question 5

Where do thrown errors propagate by default?

A
Up the call stack until a matching try/catch handles them
B
They disappear automatically
C
They restart the try block
D
They return undefined
6

Question 6

What values can be thrown in JavaScript?

A
Any value (Error objects recommended)
B
Only Error instances
C
Only strings
D
Only numbers
7

Question 7

What parameter does catch receive?

A
The value that was thrown (often an Error)
B
The filename
C
A boolean indicating success
D
Nothing; catch has no parameter
8

Question 8

Why is try/catch considered expensive when overused?

A
It complicates control flow and may mask bugs if misused
B
It blocks the event loop
C
It prevents optimizations entirely
D
It forces global scope
9

Question 9

What does this snippet log?

javascript
try {
  throw new Error('fail')
} catch (err) {
  console.log(err.message)
}
A
fail
B
Error: fail
C
undefined
D
Nothing
10

Question 10

How does catch behave here?

javascript
try {
  JSON.parse('{ invalid }')
} catch (error) {
  console.error('Parsing failed', error.name)
}
A
Logs “Parsing failed SyntaxError”
B
Throws SyntaxError unhandled
C
Logs nothing
D
always returns null
11

Question 11

What information does err.stack typically contain?

A
A stack trace of the call sequence leading to the error
B
Only the message string
C
A boolean indicating severity
D
The JSON payload
12

Question 12

How do you throw a custom Error subclass?

A
throw new CustomError("message")
B
throw CustomError
C
throw "CustomError"
D
Custom errors cannot be thrown
13

Question 13

What does this custom error output?

javascript
class ValidationError extends Error {
  constructor(msg) {
    super(msg)
    this.name = 'ValidationError'
  }
}
try {
  throw new ValidationError('Missing email')
} catch (err) {
  console.log(err.name, err.message)
}
A
ValidationError Missing email
B
Error Missing email
C
Missing email
D
Throws because custom errors unsupported
14

Question 14

How can catch handle different error types?

A
Use instanceof checks (or custom properties) and branch accordingly
B
Define multiple catch blocks (not allowed)
C
Error types cannot be distinguished
D
Use switch(error) directly
15

Question 15

Why is throwing strings discouraged?

A
Strings lack stack traces and standardized properties
B
Strings cannot be caught
C
Strings crash the runtime
D
Strings suppress finally
16

Question 16

What does catch { ... } without a parameter do?

A
Ignores the error object when you do not need it
B
Throws syntax error
C
Automatically rethrows
D
Assigns the error to window.error
17

Question 17

Why should you avoid swallowing errors silently?

A
Silent failures make debugging impossible and hide critical issues
B
It improves performance
C
Errors automatically log elsewhere
D
Users prefer no logs
18

Question 18

What does this nested handler log?

javascript
try {
  try {
    throw new Error('inner')
  } catch (err) {
    console.log('Inner handled', err.message)
    throw err
  }
} catch (outerErr) {
  console.log('Outer handled', outerErr.message)
}
A
Inner handled inner Outer handled inner
B
Outer handled inner only
C
Unhandled error
D
Inner handled inner only
19

Question 19

How does this code handle multiple error types?

javascript
try {
  risky()
} catch (err) {
  if (err instanceof SyntaxError) {
    handleSyntax(err)
  } else if (err instanceof TypeError) {
    handleType(err)
  } else {
    throw err
  }
}
A
It branches on instanceof and rethrows unhandled errors
B
It swallows all errors
C
It only handles SyntaxError
D
It prevents outer handlers from running
20

Question 20

When should you rethrow an error after logging?

A
When the current level cannot resolve it but needs to record context before bubbling up
B
Never rethrow
C
Only for SyntaxError
D
Only inside finally
21

Question 21

What does this helper demonstrate?

javascript
function safe(fn) {
  try {
    return { ok: true, value: fn() }
  } catch (error) {
    return { ok: false, error }
  }
}
const result = safe(() => JSON.parse(data))
A
Wrapping operations to return structured success/failure objects instead of throwing
B
Try/catch cannot be inside helpers
C
safe always rethrows
D
JSON.parse never throws
22

Question 22

Why throw custom errors for validation failures?

A
Custom errors convey intent and can be caught separately from other failures
B
Built-in errors cannot be used
C
Custom errors run faster
D
Validation should never throw
23

Question 23

How can you attach metadata to errors before rethrowing?

javascript
try {
  doTask()
} catch (err) {
    err.taskId = currentTaskId
    throw err
}
A
Add properties to the Error object, then rethrow so upstream handlers can log them
B
Errors are immutable
C
This removes the original stack
D
Only message can change
24

Question 24

What does this parsing helper return on failure?

javascript
function parse(json) {
  try {
    return JSON.parse(json)
  } catch (err) {
    return null
  }
}
console.log(parse('oops'))
A
null, indicating parsing failed without throwing to callers
B
undefined
C
Throws SyntaxError
D
It logs and returns json
25

Question 25

Why should catch blocks include logging or metrics?

A
Logging captures context for debugging and alerting, preventing silent failures
B
Logging fixes the error
C
catch automatically logs
D
Metrics slow down code
26

Question 26

What does this try/finally wrapper guarantee?

javascript
let lock = acquire()
try {
  useLock(lock)
} finally {
  lock.release()
}
A
release() runs even if useLock throws, ensuring resources are freed
B
release only runs when no error occurs
C
lock.release is skipped if useLock returns
D
finally runs before try
27

Question 27

What is the effect of returning inside finally?

A
It overrides any earlier return or thrown error
B
It has no effect
C
It rethrows the original error automatically
D
It prevents finally from executing
28

Question 28

How does this async try/catch handle promise rejections?

javascript
async function loadData() {
  try {
    const data = await fetchJSON()
    return data
  } catch (error) {
    console.error('Fetch failed', error)
    return null
  }
}
A
await converts promise rejections into thrown errors that catch can process
B
await ignores rejections
C
Async functions cannot use try/catch
D
catch only runs for synchronous errors
29

Question 29

Why is finally recommended for cleanup?

A
Cleanup runs regardless of whether the guarded code succeeded or threw
B
Cleanup only runs when no error occurs
C
Cleanup runs before try
D
Cleanup is unnecessary in JS
30

Question 30

Why should asynchronous cleanup inside finally be awaited?

A
Without await, async cleanup continues in the background and errors may go unhandled
B
finally does not support async code
C
Awaiting is optional and has no effect
D
Async cleanup automatically awaits
31

Question 31

How do nested try/catch blocks aid recovery?

javascript
try {
  handleRequest()
} catch (err) {
  try {
    recover(err)
  } catch (recoverErr) {
    logCritical(recoverErr)
    throw recoverErr
  }
}
A
Inner handlers tackle specific failures while outer handlers provide fallbacks or logging
B
Nested try/catch is invalid syntax
C
Inner try blocks prevent finally from running
D
Nested handlers always swallow errors
32

Question 32

How can you avoid duplicate cleanup logic in nested handlers?

A
Extract cleanup to a shared finally block or helper function
B
Copy cleanup code everywhere
C
Skip cleanup entirely
D
Use global variables for cleanup
33

Question 33

What is the fail-fast principle?

A
Detect and surface problems immediately instead of proceeding in a bad state
B
Hide errors from users
C
Retry indefinitely
D
Log nothing
34

Question 34

Why centralize error handling in large apps?

javascript
window.onerror = (msg, url, line, col, error) => {
  reportToService({ msg, url, line, col, stack: error?.stack })
}
process.on('uncaughtException', err => {
  console.error('Fatal', err)
  notifyOps(err)
})
A
Global handlers ensure consistent logging, monitoring, and user messaging policies
B
Central handlers automatically fix bugs
C
Centralization removes the need for local try/catch
D
Centralization hides all errors
35

Question 35

What should a catch block do when it cannot recover?

A
Log context and rethrow or propagate the error to higher layers
B
Ignore it silently
C
Convert every error to console.log only
D
Swallow it to keep UI clean
36

Question 36

What best practice applies when wrapping third-party calls?

A
Wrap them in try/catch to log failures and provide user-friendly fallbacks
B
Assume dependencies never fail
C
Do not log dependency errors
D
Swallow all errors from third parties
37

Question 37

Why should logs include contextual data such as user actions or identifiers?

A
Context helps engineers reproduce and diagnose problems faster
B
Context is unnecessary
C
Logs should be minimal to avoid clarity
D
Context automatically fixes the bug
38

Question 38

How does try/catch interact with asynchronous callbacks (not using async/await)?

A
Errors thrown inside asynchronous callbacks are not caught by outer try/catch; handle them inside the callback
B
Outer try/catch handles all async errors automatically
C
Callbacks cannot throw
D
setTimeout absorbs all errors
39

Question 39

Why convert user-facing errors into friendly messages?

A
Users need actionable feedback while technical details remain in logs
B
Users should see raw stack traces
C
Friendly messages fix the underlying bug
D
It is unnecessary in production
40

Question 40

Which statement summarizes robust error handling?

A
Handle errors at the right layer, log context, clean up resources, rethrow when appropriate, and avoid silent failures
B
Suppress all errors to keep the console clean
C
Rely on finally to fix bugs automatically
D
Throw strings for simplicity

QUIZZES IN JavaScript