Challenge your understanding of structured error handling, error codes vs. exceptions, adding context, managing retries, and resource cleanup in robust software systems.
Propagating Errors with Exceptions
When a function detects an unexpected error and uses an exception to signal it to a caller, what is the main advantage over returning an error code?
- Exceptions always execute faster than error codes.
- Exceptions guarantee that resources are freed automatically.
- Exceptions separate error-handling logic from business logic more cleanly.
- Exceptions cannot be missed by the caller.
- Exceptions require less code than error codes in all cases.
Error Context Enhancement
Given a scenario where an error occurs deep within a series of function calls, what technique best improves diagnosability when the error is propagated?
- Returning only generic error codes from each function.
- Wrapping the error with contextual information at each level.
- Logging errors only at the highest level.
- Using ambiguous return values to hide specifics.
- Silently discarding errors to avoid confusion.
Error Codes vs. Exceptions
Which of the following is a significant challenge when using error codes instead of exceptions for error propagation in large codebases?
- Error codes improve type safety in all languages.
- Error codes automatically escalate to the highest level.
- Error codes prevent any form of resource leakage.
- Error codes provide stack traces on their own.
- Forgetting to check the return code at every function call.
Retry Logic Placement
In implementing automatic retries for transient failures, where should retry logic ideally reside to maximize code reuse and clarity?
- In a dedicated wrapper or middleware around the operation.
- Statically coded within each resource object.
- Spread across helper scripts with no centralized control.
- Inlined within the main application loop for all operations.
- Inside every individual function that makes an external request.
Resource Cleanup with Exceptions
When handling exceptions, what construct or technique is most reliable for ensuring that resources such as files or locks are always released?
- Relying on garbage collection alone for all resources.
- Skipping cleanup if the program is about to exit.
- Placing cleanup code randomly in the function body.
- Using a 'finally' block or a destructor-like cleanup mechanism.
- Only releasing resources when no exceptions are raised.
Adding Context to Errors
When rethrowing an error after catching it, which practice best preserves detailed information for troubleshooting?
- Ignoring the stack trace to avoid confusion.
- Appending contextual data about the current state before propagating.
- Masking the error code with a generic one.
- Suppressing the error message for security.
- Converting the exception to a warning.
Idempotency in Retry Logic
Why must operations be idempotent when implementing automatic retries after errors such as timeouts?
- Because idempotency enforces input validation.
- Because non-idempotent operations cannot fail.
- To ensure retries are faster than initial attempts.
- So that errors are automatically logged.
- To prevent unintended effects from repeated executions.
Structured vs. Unstructured Error Handling
Which aspect best distinguishes structured error handling from unstructured error handling in complex software systems?
- Use of typed exceptions or return values with semantic meaning.
- Suppressing all errors unless fatal.
- Frequent use of global variables to signal errors.
- Printing error messages directly to the console.
- Ignoring function return values by default.
Exception Safety and Resource Ownership
In code that acquires multiple resources, what principle helps avoid leaks if an exception interrupts the sequence?
- Polling resource states instead of releasing.
- Delaying exception handling for performance.
- Immediate resource ownership transfer to a managing scope object.
- Only acquiring resources after error-prone operations.
- Deferring all acquisition to just before resource release.
Error Handling Granularity
When deciding at what level to catch and handle exceptions, which strategy generally leads to the most maintainable code?
- Catching exceptions in the middle of the call stack regardless of context.
- Always catching and logging exceptions immediately at point of origin.
- Catching all exceptions globally and ignoring all details.
- Never catching exceptions, allowing uncontrolled program abort.
- Catching exceptions at the highest layer that can respond meaningfully.