Very often, I have to use multiple libraries that handle errors differently or define their own enums for errors. This makes it difficult to write functions that might have to deal with errors from different sources, and then return its own error code. For example:
int do_foo_and_bar()
{
int err;
if ((err = libfoo_do_something()) < 0) {
// return err and indication that it was caused by foo
}
if ((err = libbar_do_something()) < 0) {
// return err and indication that it was caused by bar
}
// ...
return 0;
}
I've thought of two possible solutions:
- Create my own list of error codes and translate these error codes to new ones, using functions like
int translate_foo_error(int err)
, and I would write my own string representations for each error. - Create a
struct my_error
that holds both an enum identifying the library and the error code. The translation to string would be delegated to an appropriate function for each library.
This seems like a problem that would come up very often, so I'm curious, how is this usually handled? It seems like the former is what most libraries do, but the latter is less work and plays on the tools already provided. It doesn't help that most tutorials just print a message to stderr and exit on any error. I'd rather have each function indicate what went wrong, and the caller can decide from that how to handle it.