We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Errors step 2 of 4
Catch exceptions without slicing their type
The supplied fetch function throws one of two error types. Both derive from AppError, so one handler can catch either. How that handler declares its parameter determines whether it can still observe the specific error type.
Catch by const reference
The starter uses:
catch (AppError e) {
return e.code();
}
If fetch throws NotFound, this creates a separate AppError object from the base part of the exception. That new object's type is AppError, so code() returns 500. The original exception is still a NotFound; the handler's local copy has lost the derived behavior. This is object slicing.
A reference avoids creating that base-only copy:
catch (const AppError& e) {
return e.code();
}
Now e refers to the base part of the original exception, whose dynamic type remains NotFound or Denied. Virtual dispatch calls that derived type's code() override. const makes this access read-only.
The issue is the separate base object, not a general rule that virtual functions cannot be called on local objects. A standalone NotFound object also calls its own override. Copying it into a standalone AppError changes which object the later call uses.
Throwing and rethrowing
Prefer throwing an exception object by value, such as throw NotFound{};.
throw new NotFound{}; throws a pointer instead, which the AppError reference
handler does not catch and whose allocated object needs separate ownership.
Within a handler, throw; rethrows the currently handled exception and retains
its dynamic type. In contrast, throw e; creates a new exception from the
expression's static type. If e is declared as const AppError&, that new
exception is an AppError even though the reference still refers to a NotFound.
Use a bare rethrow when the original exception should continue outward.
Handlers are considered in source order. Put a specific derived-type handler before a base-type handler if they need different treatment. A final catch (...) can handle any exception at an appropriate boundary, translate a failure or rethrow it. Its behavior should follow the surrounding API's error contract.
Choosing and measuring an error mechanism
Whether a missing key is an error depends on the API: a lookup may return an optional result, while an operation that requires the key may report failure. There is no universal rule forbidding exceptions in loops. Avoid using them for routine iteration when a normal condition expresses the operation clearly.
Exception cost depends on the implementation, compiler options and workload. Throwing can involve exception-object storage, finding a handler and unwinding through destructors. C++ does not promise a fixed cost ratio or that enabling exceptions leaves the normal path unchanged. Measure relevant code before making performance claims. This exercise checks behavior, not exception timing.
Your task
Correct handle's catch parameter. Leave its return expressions, fetch and the exception classes unchanged:
int handle(int request);
| Request | fetch behavior | Required handle result |
|---|---|---|
| Less than 0 | Throws Denied | 403 |
| 0 through 100, inclusive | Returns request * 10 | That returned value |
| Greater than 100 | Throws NotFound | 404 |
Inputs fit int. Successful multiplication is limited to 0..100, so it cannot
overflow int. For requests [5, -1, 200, 100], the harness returns
[50, 403, 404, 1000]. It calls handle separately for each request; a handled
failure does not skip later requests. An empty request list produces [].
The starter returns 500 for both application errors because it slices their type into AppError. Preserve their dynamic type when catching them. Do not change the exception codes or replace the supplied fetch behavior.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
C++ reference solution
Sign in to track your attempts toward unlocking the reference solution.