C++ Error Reporting Interface
I'm designing an interface that can be use开发者_StackOverflowd to report errors in C++. (I'm working with a legacy system where exceptions are out of question.) In my youthful naivety, I started along these lines while designing my API:
bool DoStuff(int amount, string* error);
Return value signals success/failure, while error is used to report a human readable explanation. So far so good. Subroutine calls passed along the error pointer and everything was hunky-dory.
I ran into the following problems with this design (so far):
- Cannot report warnings.
- Not thread-safe.
Next, I decided to go with the following interface, instead of plain string:
class Issues {
public:
void Error(const string& message);
void Warning(const string& message);
void Merge(const Issues& issues);
}
So that I can change my API like this:
bool DoStuff(int amount, Issues* issues);
I'm wondering, is there a more generic/standard API out there that deals with this problem? If yes, I'd like to take a look.
UPDATE: I'm not looking for a logging library. For those who are curious, imagine you're writing a query engine that includes a compiler. The compiler issues warnings and errors, and those need to be returned to the user, as part of the response. Logging has its place in the design, but this is not it.
I usually use things like boost::signals
or .NET delegates to report errors/warning/logging/whatever. You report errors with no changes to the interface, and the library user plugs whatever she wants to the signal to get the error reports (writing to a file, updating a console window, aborting the program, throwing an exception, ignoring warnings, etc).
Something like this, at eg. global scope:
boost::signal<void(std::string const&)> logError;
boost::signal<void(std::string const&)> logWarning;
and then
void routineWhichMayFail()
{
...
if (answer != 42)
{
logError("Universal error");
return;
}
}
and you connect something to logError
and logWarning
at initialization:
void robustErrorHandler(std::string const& msg)
{
std::cerr << "Error: " << msg << "\n";
std::exit(EXIT_FAILURE);
}
void initializeMyProgram()
{
logError.connect(&robustErrorHandler);
}
You can even throw exceptions in the error handler instead of exiting, and use fancier things than bare functions (logging classes, "delegates" -- pointers to methods with a this
object bundled, RPC to a distant server). This way, you decouple the error handling from error reporting, which is good. You can also report to multiple destinations, you can even have your handlers return a boolean telling whether the action should be eg. retried.
From your explanation it sounds like you are trying to implement a logging library for your project. You can look at log4cpp or Boost.Log.
精彩评论