Skip to content
tezvyn:

Top 30 Error Handling Interview Questions and Answers

30 multiple-choice questions on Error Handling, drawn from 30 bites out of the 56 tagged Error Handling on Tezvyn. Answer them here or read straight down. Every question carries the correct option, why it is correct, and a link to the bite it came from.

30 questions. Pick an answer, or open “Show the answer” to read it.

Answers are graded in your browser. Nothing is saved, and no XP or streak is earned here. The app keeps score.

  1. Question 1 of 30

    You add a new variant to an error type during a large refactor. Why does Rust typically surface every place needing an update more reliably than Go?

    Show the answer

    Answer: d · Rust's exhaustive match makes non-updated handling sites fail to compile

    Adding an enum variant makes existing exhaustive matches incomplete, so Rust's compiler flags each site. Go's error values do not force callers to branch, so it does not flag missed sites; Rust does not auto-rewrite code.

    Read the full bite: Refactoring under Go simplicity versus Rust correctness

  2. Question 2 of 30

    What happens if a caller ignores the error when parsing a string to an integer in Go versus Rust?

    Show the answer

    Answer: d · Go compiles silently because error checking is purely conventional, while Rust emits a must-use warning since Result is enforced by the type system

    Go relies on programmer discipline to check the second error return value, so ignored errors compile silently. Rust's Result is must-use, so the compiler warns if it is not handled via match or ?; distractor A reverses these roles.

    Read the full bite: Parse a string to integer in Go and Rust with errors

  3. Question 3 of 30

    In classic Express 4, how should an error from an awaited database call inside async middleware reach the error handler?

    Show the answer

    Answer: c · Catch it and pass it to next(err) so the error-handling middleware runs

    Express 4 does not auto-catch async throws, so you must catch and forward with next(err) to trigger the four-argument error handler. Throwing alone leaves the request hanging.

    Read the full bite: Handling async errors in Express middleware

  4. Question 4 of 30

    Which statement accurately describes how to consume a Future<String> and handle errors idiomatically in Dart?

    Show the answer

    Answer: b · Use an async function with try/catch around an await, or chain .then() with .catchError() on the Future.

    Option B correctly identifies both callback-style and async/await patterns for handling values and errors. Option A is wrong because a Future<String> is a pending object, not an actual String, so assigning it directly causes a type mismatch and synchronous try/catch cannot catch its asynchronous errors.

    Read the full bite: Define a Dart Future, return Future<String>, and handle errors with both patterns.

  5. Question 5 of 30

    Why might a try/catch fail to catch an error from an async call inside it?

    Show the answer

    Answer: b · If the returned Promise is not awaited, control leaves the block before it rejects

    Without await, the async call returns a pending Promise and execution exits the try block immediately, so a later rejection is not caught there. Awaiting the call keeps it within the try/catch scope.

    Read the full bite: Comparing the three async error-handling styles

  6. Question 6 of 30

    What is the practical consequence of declaring an async Dart function as void instead of Future<void>?

    Show the answer

    Answer: a · The caller gets no Future handle, so they cannot await completion or catch async errors.

    A void return type hides the implicit Future from the caller, which prevents awaiting completion and catching errors with try/catch. Option C is tempting but wrong because without a Future handle, exceptions become uncaught async errors instead of propagating to the caller.

    Read the full bite: Difference between Future<void> and void from an async function

  7. Question 7 of 30

    What happens when you call .sum() directly on an iterator of Option<i32> that includes a None?

    Show the answer

    Answer: c · It returns None, short-circuiting the summation

    The Sum<Option<U>> implementation returns None if any element is None, short-circuiting the entire operation. The other choices confuse this behavior with unwrap panics or assume automatic coercion of missing values.

    Read the full bite: Sum Some values in Vec<Option<i32>>, ignoring None

  8. Question 8 of 30

    When is Promise.allSettled the better choice over Promise.all?

    Show the answer

    Answer: c · When each operation is independent and you need every outcome, including failures, reported

    allSettled waits for every input and reports each outcome, ideal when partial success is acceptable and you must see all failures. all aborts on the first rejection, hiding other results.

    Read the full bite: Promise.all vs Promise.allSettled

  9. Question 9 of 30

    In a FastAPI application, when is it appropriate to explicitly raise HTTPException?

    Show the answer

    Answer: b · To signal that a requested resource or business rule violation occurred due to client input.

    HTTPException is designed for expected, client-caused errors like a missing resource (404) or a permission issue (403), which stem from business logic. FastAPI automatically handles Pydantic validation errors (422) and it's not for unexpected server bugs (500).

    Read the full bite: FastAPI: Use HTTPException to Return Client Errors

  10. Question 10 of 30

    A Go function returns (User, error). What must the caller do before using the User value?

    Show the answer

    Answer: c · Check whether the error is non-nil and handle it before using User

    Go conventions require checking if the error is non-nil before using the result, since a non-nil error signals that the other return value is a zero value and unsafe to use. Option B is tempting but wrong because the zero-value result may not be nil, and the error is the authoritative success signal.

    Read the full bite: How do you idiomatically return a recoverable error and result in Go?

  11. Question 11 of 30

    What happens when a Result returned by a function is completely ignored in Rust?

    Show the answer

    Answer: c · The compiler issues a warning because Result is annotated with must_use

    Result carries the must_use attribute, so ignoring it triggers an unused_must_use compiler warning by default, not a hard error. Option B is tempting but wrong because compilation still succeeds unless the warning is explicitly elevated to deny.

    Read the full bite: What are Rust Result's variants and how does the compiler enforce handling?

  12. Question 12 of 30

    What distinguishes an Express error-handling middleware from a regular one?

    Show the answer

    Answer: a · It has four parameters (err, req, res, next), and Express detects this signature

    Express identifies error handlers by their four-argument arity and routes errors to them. The name is irrelevant, there is no app.error method, and it is still registered with app.use.

    Read the full bite: Centralized error-handling middleware

  13. Question 13 of 30

    When some_call()? evaluates to Err inside a function returning Result, what happens?

    Show the answer

    Answer: a · It immediately returns the Err from the current function

    The ? operator immediately returns the Err from the current function, enabling propagation via the Try and FromResidual traits, whereas unwrap panics on Err rather than returning to the caller.

    Read the full bite: Rust's operator equivalent to Go's if err != nil return err

  14. Question 14 of 30

    An error wrapped with fmt.Errorf using %w contains an underlying *os.PathError. Which approach lets you safely extract its Path field?

    Show the answer

    Answer: d · Use errors.As with a pointer to a *os.PathError variable

    errors.As traverses the unwrap chain and copies a matching *os.PathError into the target pointer so you can read its Path field. A direct type assertion only inspects the top-level error and silently fails when wrapping is present.

    Read the full bite: Difference between errors.Is and errors.As in Go

  15. Question 15 of 30

    When is it appropriate to use unwrap or expect in production Rust code?

    Show the answer

    Answer: b · When an invariant is statically guaranteed, such as parsing a compile-time embedded asset that must exist

    unwrap and expect are intended for unrecoverable invariant violations, not routine errors, and the card explicitly cites statically guaranteed cases like compile-time assets as legitimate production uses. Distractor B is tempting because many developers believe panicking is never acceptable in production, but the card identifies this as dogmatic overcorrection that ignores justified scenarios like poisoned mutexes or bundled static assets.

    Read the full bite: What is the difference between unwrap and expect on Option and Result?

  16. Question 16 of 30

    What must you implement to let the ? operator automatically convert std::io::Error into a custom enum error type?

    Show the answer

    Answer: b · Implementing From<std::io::Error> for the custom enum

    The ? operator desugars to a match that returns Err(From::from(err)) on failure, so implementing From<std::io::Error> for the custom enum is what enables automatic conversion. Manually using map_err on every call site is a common misconception that creates unnecessary boilerplate instead of leveraging the type system.

    Read the full bite: How does the question mark operator use From to unify error types?

  17. Question 17 of 30

    When defining a custom struct-based error type that wraps an underlying error to add context, which implementation choice is required for errors.Is and errors.As to traverse the wrapper?

    Show the answer

    Answer: d · Implement an Unwrap method returning the underlying error field

    errors.Is and errors.As rely on the Unwrap method to walk the chain; without it, they cannot reach the underlying sentinel even if Error surfaces its text. Simply exposing a field or stringifying with %v does not provide the unwrapping contract.

    Read the full bite: Design a custom Go error type with context, Is, As, and Unwrap

  18. Question 18 of 30

    Inside an async function's try block you call doWork() without awaiting it, and it rejects. What happens?

    Show the answer

    Answer: c · The rejection escapes the try/catch and becomes an unhandled rejection

    try/catch only catches rejections of promises you actually await; an unawaited call's rejection escapes the block. There is no auto-retry, and TypeScript does not require await to compile.

    Read the full bite: Promise .catch() versus async/await try...catch

  19. Question 19 of 30

    When is reaching for panic (or unwrap) appropriate in idiomatic Go and Rust?

    Show the answer

    Answer: b · For unrecoverable bugs or violated invariants, while expected failures use error or Result values

    Both languages reserve panic for unrecoverable programmer errors and broken invariants, returning error or Result for expected failures. Using panic for routine validation or expected input errors is an anti-pattern in both.

    Read the full bite: When to panic in Go versus Rust

  20. Question 20 of 30

    You wrote an error handler as (req, res, next) and errors passed via next(err) never reach it. What is the fix?

    Show the answer

    Answer: b · Declare four parameters: (err, req, res, next)

    Express identifies error handlers by their four-argument arity; three params make it a regular middleware that skips error propagation. Position alone does not fix the signature.

    Read the full bite: Express error-handling middleware signature

  21. Question 21 of 30

    Why should an automatic retry-with-backoff strategy generally exclude HTTP 4xx responses?

    Show the answer

    Answer: d · 4xx indicates a flawed request, so repeating it unchanged will keep failing

    A 4xx means the client request is invalid, so retrying it without change yields the same error; only transient 5xx or connectivity issues benefit from backoff. 4xx are application-layer responses, not network failures, so that option is wrong.

    Read the full bite: Robust network error handling strategy

  22. Question 22 of 30

    When using fetch, how can you ensure both network failures and HTTP 404 errors are handled by the same catch block?

    Show the answer

    Answer: b · Check response.ok in the then handler and throw an error if false, before parsing the body

    fetch resolves for HTTP error statuses, so you must inspect response.ok and throw manually to reach the catch block. A second catch block is ineffective because 4xx and 5xx responses do not trigger rejection.

    Read the full bite: How would you modify fetch to handle HTTP error statuses?

  23. Question 23 of 30

    In an async TypeScript function fetchUser(id: number): Promise<User> that wraps fetch, what is the primary reason to check response.ok before calling response.json()?

    Show the answer

    Answer: c · fetch resolves even on 4xx or 5xx statuses, so ok is needed to detect HTTP failures before parsing.

    fetch resolves rather than rejects on HTTP error codes such as 404 or 500, so checking response.ok is the only way to detect server-side failures before parsing. Distractor A repeats the common misconception that fetch auto-rejects on 4xx/5xx, which would make the ok check unnecessary.

    Read the full bite: Write a typed async fetchUser with error handling

  24. Question 24 of 30

    In a generic fetchJson wrapper, why is it critical to check response.ok before returning res.json() as Promise<T>?

    Show the answer

    Answer: d · Because fetch resolves even on 4xx/5xx statuses, so skipping the check would return an error payload incorrectly typed as T.

    fetch resolves successfully on HTTP error codes such as 404 or 500, so without the ok guard the caller would receive an error body wrongly typed as T. Option A is a tempting misconception because fetch only rejects on network failures, not on HTTP error statuses.

    Read the full bite: Create a generic fetchJson wrapper with typed response and error handling

  25. Question 25 of 30

    GET /products/999 finds no such product, and separately a query fails because the database is unreachable. What status codes fit each case?

    Show the answer

    Answer: d · 404 for the missing product, 500 (or 503) for the database failure

    A missing resource is a client-facing 404; a server-side database outage is a 5xx (500, or 503 if transient). Using the same code for both would conflate normal misses with real incidents.

    Read the full bite: 404 vs 500: missing resource vs server failure

  26. Question 26 of 30

    In an Express 4 API with a central error middleware, async route errors still hang the request while sync throws work fine. What is missing?

    Show the answer

    Answer: b · An asyncHandler wrapper that catches promise rejections and calls next

    Express 4 auto-catches synchronous throws but not promise rejections, so async handlers need a wrapper that forwards rejections to next. Moving the error handler before routes would actually break it.

    Read the full bite: Centralized error handling in an Express API

  27. Question 27 of 30

    Which strategy best distinguishes a transport timeout from a malformed JSON payload when using Dio?

    Show the answer

    Answer: c · Check DioExceptionType for connectivity issues, then parse JSON in a separate try-catch after confirming HTTP success

    The correct answer reflects the layered approach: inspect DioExceptionType for transport failures first, then isolate JSON deserialization in its own try-catch so schema mismatches are not confused with wire errors. Option B is wrong because a generic catch block makes it impossible to tell whether the failure came from the network or the mapper.

    Read the full bite: Describe a robust error handling strategy for network requests

  28. Question 28 of 30

    For which scenario is Rust's Option<T> type most appropriately used?

    Show the answer

    Answer: c · When a function's return value might genuinely not exist, requiring the caller to explicitly check for its presence.

    Option<T> is designed for situations where a value might be absent, forcing compile-time handling of that possibility, as described for function returns that can fail. Option D describes the use case for Result<T, E>, which provides specific error details.

    Read the full bite: Rust's Option<T>: Handling Absence Safely

  29. Question 29 of 30

    In Rust, for which scenario is the `?` operator most effectively employed?

    Show the answer

    Answer: c · When chaining several fallible operations and you want to propagate any encountered error up to the calling function.

    The `?` operator is specifically designed to propagate `Err` or `None` values up the call stack, making it ideal for chaining fallible operations while keeping the success path clean. It is not used for immediate, specific error handling like logging or retrying, nor is it applicable in functions that do not return a `Result` or `Option`.

    Read the full bite: Rust's Question Mark Operator (?): Propagate Errors, Not Boilerplate

  30. Question 30 of 30

    Which pair correctly matches the modern idiomatic convenience function to its return type?

    Show the answer

    Answer: a · Go os.ReadFile returns ([]byte, error); Rust std::fs::read returns Result<Vec<u8>>

    Go 1.16 introduced os.ReadFile returning ([]byte, error), while Rust's std::fs::read returns Result<Vec<u8>>. Option D is tempting because ioutil.ReadFile did return that type, but it has been deprecated since Go 1.16.

    Read the full bite: Read a file into a byte slice in Go and Rust

Could you explain these out loud?

That is what an interview actually tests. Tezvyn gives you questions like these with what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon