When writing a function, my implementation very frequently looks like this:
- Call a subfunction
- If this subfunction fails to execute (because of an exceptional situation): log this failure and abort the current function
- Otherwise continue calling other subfunctions, which in turn can fail
A crucial part is the logging. Every function that fails should add a short description to the log. This way, at the level where the exception is handled, the user can be shown a detailed error message.
For example, consider an application where a new user account can be created, and there is a problem with the database connection. The following inverse stack trace results:
- SQLDriverConnect() -> "SQLDriverConnect error: Data source not found and no default driver specified"
- OpenDatabaseConnection() -> "Failed to open database connection"
- CreateUser() -> "Failed to create the new user"
- ValidateAndSaveNewUserAccount() -> "Failed to save the user profile"
- Catch the exception and show the logged messages to the user
Using the exceptions feature, I would implement this as follows:
void CreateUser()
{
try {
OpenDatabaseConnection();
}
catch(std::exception& e) {
e.AddLog("Failed to create the new user");
throw;
}
//...
}
Using a simple return value, I'd write the following:
bool CreateUser(Log& log)
{
if (!OpenDatabaseConnection(log))
{
log.Add("Failed to create the new user");
return false;
}
//...
return true;
}
I find both implementations equally good. Therefore, I don't see much advantage in using exceptions. I am well aware that exception handling is generally considered a useful feature, but I don't really understand why. A long time ago, I used exception handling extensively, but I didn't see the big advantage, so now I never use them anymore. Hence my questions:
- Using exceptions, how can this be implemented in C++ more concisely?
- If not, what is then the advantage of throwing exceptions over returning an "is successful" boolean?
Note: I use the term logging as "collecting an explanation of what went wrong, so it can be presented to the user later on". I'd rather not store that explanation in a global collection of log messages (in memory, in a file or in a database), as it directly describes the specific exception.
Update: Thanks for you responses so far. I understand that exceptions are only useful if the user doesn't need detailed feedback on what went wrong. (Please correct me if I misinterpreted this.)