C++11 (or Boost) system_error strategy - c++

I'm working on a system which is designed to use the classes called error_code, error_condition, and error_category -- a scheme newly std: in C++11, altho at the moment I'm actually using the Boost implementation. I've read Chris Kholkoff's series of articles, three times now, and I think I understand how to create these classes generally.
My issue is that this system needs to handle plugins which exist in individual DLLs, and the plugins may issue errors. My original design was planning one system-specific error category that would encompass all the various error codes and a shortlist of specific error conditions that don't really map to the errno values. The problem here is that for the DLL to be able to use one of these error codes, it needs access to the sole instance of the error_category in the app. I'm handling this now by exporting a SetErrorCategory() function from each DLL, which works but is kinda icky.
The alternate solution I see is that each DLL has its own error category and codes, and if needed, its own conditions; I suspect this is more like what was envisioned for this library feature. But, I think this requires a comparison function in the main app's error scheme that knows about the plugins' error schemes and can check which of the app's conditions match the plugin's error. This seems even more prone to a bunch of problems, altho I haven't tried to implement it yet. I'm guessing I'd have to export the entire error scheme from the DLL, on top of all the actual logic.
Another way to do this, of course, is to just use numeric error codes from the DLL and stuff them into error objects on the app side. It has the advantage of simplicity for the plugin, but could lead to gotchas in the app (e.g., a function juggling objects from a couple different plugins needs to pay attention to the source of each error).
So my specific question is: of those three options, which would you use, and why? Which is obviously unworkable? And of course, is there a better way that hasn't occurred to me?

The solution I arrived at when working on this problem was to use predefined codes for the family of problem and user subcode selection along with inheritance for the specific type of error. With boost this lets me inherit the specific type by:
struct IOException : virtual std::exception, virtual boost::exception {};
struct EOFException : IOException {};
...
and leave the error code matching the predefined general errors like IOException. Thus I can have a general code range for each family of error:
namespace exception { namespace code {
UNKNOWN_EXCEPTION = 0;
IO_EXCEPTION = 100;
CONCURRENCY_EXCEPTION = 200;
...
}}
Then if someone wants a new error type they can inherit from a generic exception type that's already defined and the code that goes along with that error and specialize the exception by inheritance type and minor value (0-99). This also allows for try catch blocks to catch more specific error types while lettings more general versions of the exception pass to other control blocks. The user is then free to use the parent exception code or specify their own code which is within the family (parent = 100 -> child = 115). If the user just wants an IOError, without creating a new family of errors, they can just use the default family exception with no hassle. I found this gave the user flexibility without requiring OCD tracking of exception codes when they don't want it.
However this is by no means the end-all solution, as personal preference led my design choices here. I find the having too many error codes becomes confusing and that exception inheritance already encodes this information. Actually, in the system I described it's easy to strip out error codes entirely and just rely on exception inheritance, but many people prefer having a code assigned to each exception name.

I figured out another solution: Create one DLL that contains only my error_category implementation, and link to it from the app and from each plugin DLL. This gives them all access to the global category object, without having to explicitly pass that object from the app to the DLL.

Related

Which is more memory/performance efficient for static error strings, or are there alternatives?

I would like an opinion on what is the best way to handle static error strings in C++. I am currently using a number of constant char pointers, but they get unwieldy, and they are scatter every where in my code. Also should I be using static constant char pointers for these strings?
I was thinking about defines, hash tables, and INI files using the SimpleIni class for cross-platform compatibility. The project is an always running web server.
I would like to use error numbers or names to refer to them logically.
I am using the global space and methods contained in namespaced classes if that helps. The code is exported to C because of the environment if that helps as well.
Thanks
There are several things in tension here, so let me please enumerate them:
centralization / modularity: it is normal to think about centralizing things, as it allows to easily check for the kind of error one should expect and recover an error from an approximate souvenir etc... however modularity asks that each module be able to introduce its new errors
error may happen during dynamic initialization (unless you ban code from running then, not easy to check), to circumvent the lifetime issue, it is better to only rely on objects that will be initialized during static initialization (this is the case for string literals, for example)
In general, the simplest thing I have seen was to use some integral constant to identify an error and then have a table on the side in which you could retrieve other information (potentially a lot of it). For example, Clang uses this system for its diagnosis. You can avoid repeating yourself by using the preprocessor at your advantage.
Use such a header:
#define MYMODULE_ERROR_LIST \
ERROR(Code, "description") \
...
#define ERROR(Code, Desc) Code,
class enum ErrorCode: unsigned {
MYMODULE_ERROR_List
NumberOfElements
};
#undef ERROR
struct Error {
ErrorCode code;
char const* description;
};
Error const& error(ErrorCode ec);
And a simple source file to locate the array:
#define ERROR(Code, Desc) { Code, Desc },
Error const ErrorsArray[] = {
MYMODULE_ERROR_LIST
{ErrorCode::NumberOfElements, 0}
};
Error const& error(ErrorCode const ec) {
assert(unsigned(ec) < unsigned(ErrorCode::NumberOfElements) &&
"The error code must have been corrupted.");
return ErrorsArray[ec];
} // error
Note: the price of defining the macro in the header is that the slightest change of wording in a description implies a recompilation of all the code depending on the enum. Personally, my stuff builds much faster than its tested, so I don't care much.
This is quite an efficient scheme. As it respects DRY (Don't Repeat Yourself) it also ensures that the code-description mapping is accurate. The ERROR macro can be tweaked to have more information than just a description too (category, etc...). As long as the Error type is_trivially_constructible, the array can be initialized statically which avoids lifetime issues.
Unfortunately though, the enum is not so good at modularity; and having each module sporting its own enum can soon get boring when it comes to dealing uniformly with the errors (the Error struct could use an unsigned code;).
More involved mechanisms are required if you wish to get beyond a central repository, but since it seemd to suit you I'll stop at mentioning this limitation.
First of all, you can check other related questions on stackoverflow. Here you have some:
C++ Error Handling -- Good Sources of Example Code?
Exceptions and error codes: mixing them the right way
Then have a look at this great tutorial on error handling (it is a five parts tutorial, but you can access all of them from that link). This is especially interesting if you are using C++11, since it provides many more features for error handling. Alternatively you could use boost if you cannot use C++11.
You also need to consider whether you want to include support for localization. If your application may present messages to the users in different languages, it is better if you include that requirement from the very beginning in the error management too. You can check Boost.Locale for that, for instance.
I'd keep it simple, in a header:
enum ErrorCode { E_help, E_wtf, E_uhoh };
const char* errstr(ErrorCode);
Then in some .c or .cc file:
const char* error_strings[] = {
"help!",
"wtf?",
"uh-oh"
};
const char* errstr(ErrorCode e) { return error_strings[e]; }
Not a lot of detail in your question, but with what you've posted I would consider a singleton class for handling your error messages. You could create methods for accessing messages by code number or enum. Then you can implement internationalization or whatever else you need for your specific application. Also, if you do decide to use SQLite or some other file-based solution in the future, the class interface can remain intact (or be extended) minimizing impact on the rest of your code.

The error representation and handling

I am designing a cross-platform application protection library to communicate with a dongle. The dongle is able to send and receive blocks of data, to create and delete directories and files inside the dongle's internal file system, etc. To put it simple, the main dongle object has methods to implement all of these functionalities. Unfortunately, any of these methods may fail. Right now I am thinking about what to do if they do :)
The most obvious solution is to return a boolean type result from all of these methods to indicate if they fail or success. However, this leads to a loss of details about the nature of an error.
The next possible solution is to return an error code, but there will be more then 30 types of errors. Also, I will need to design a separate function to convert all of these return codes to a more readable string representation.
The third solution is to return a boolean type result, but to keep an error state object in the main dongle object so it will be possible to retrieve it using GetLastError() like method. I am considering about using this one.
Now is my question. Are there any other reasonable error representation and handling patterns and what do you suggest me to use in my case?
Thanks,
Ilya
Of the options you have presented, the best is to use return codes. Typically a return code of zero indicated success, and each other return code has its own positive integral value. 30 error conditions isn't many. As you've said, you'll have to write code to translate these codes to something human-readable, but you have to do this anyway.
I would consider writing an exception hierarchy to do this instead of error codes, however. Exceptions can be more expressive than return codes, and the code can be cleaner if done properly. You would typically design your library so that there is a different exception class for each type of error return condition, each derived ultimately from std::exception. The what() method gives you a place to put the human-message building, and the type of the exception itself describes the error.
There are those who will tell you that exceptions are "only" for exceptional circumstances, like your computer caught fire, or something. This is a hotly debated assertion. I'll tell you that is nonsense. Just because it is named "exception" doesn't mean your computer has to catch fire in order to use it. Exceptions give you a lot of benefits, one of the biggest being stack unwinding. Preventing yourself from using them simply because of some arbitrary line where errors are "bad enough" is silly.
You could also try using std::exception. It allows you to say what the error is and the nature behind it.

What's a good, threadsafe, way to pass error strings back from a C shared library

I'm writing a C shared library for internal use (I'll be dlopen()'ing it to a c++ application, if that matters). The shared library loads (amongst other things) some java code through a JNI module, which means all manners of nightmare error modes can come out of the JVM that I need to handle intelligently in the application. Additionally, this library needs to be re-entrant. Is there in idiom for passing error strings back in this case, or am I stuck mapping errors to integers and using printfs to debug things?
Thanks!
My approach to the problem would be a little different from everyone else's. They're not wrong, it's just that I've had to wrestle with a different aspect of this problem.
A C API needs to provide numeric error codes, so that the code using the API can take sensible measures to recover from errors when appropriate, and pass them along when not. The errno.h codes demonstrate a good categorization of errors; in fact, if you can reuse those codes (or just pass them along, e.g. if all your errors come ultimately from system calls), do so.
Do not copy errno itself. If possible, return error codes directly from functions that can fail. If that is not possible, have a GetLastError() method on your state object. You have a state object, yes?
If you have to invent your own codes (the errno.h codes don't cut it), provide a function analogous to strerror, that converts these codes to human-readable strings.
It may or may not be appropriate to translate these strings. If they're meant to be read only by developers, don't bother. But if you need to show them to the end user, then yeah, you need to translate them.
The untranslated version of these strings should indeed be just string constants, so you have no allocation headaches. However, do not waste time and effort coding your own translation infrastructure. Use GNU gettext.
If your code is layered on top of another piece of code, it is vital that you provide direct access to all the error information and relevant context information that that code produces, and you make it easy for developers against your code to wrap up all that information in an error message for the end user.
For instance, if your library produces error codes of its own devising as a direct consequence of failing system calls, your state object needs methods that return the errno value observed immediately after the system call that failed, the name of the file involved (if any), and ideally also the name of the system call itself. People get this wrong waaay too often -- for instance, SQLite, otherwise a well designed API, does not expose the errno value or the name of the file, which makes it infuriatingly hard to distinguish "the file permissions on the database are wrong" from "you have a bug in your code".
EDIT: Addendum: common mistakes in this area include:
Contorting your API (e.g. with use of out-parameters) so that functions that would naturally return some other value can return an error code.
Not exposing enough detail for callers to be able to produce an error message that allows a knowledgeable human to fix the problem. (This knowledgeable human may not be the end user. It may be that your error messages wind up in server log files or crash reports for developers' eyes only.)
Exposing too many different fine distinctions among errors. If your callers will never plausibly do different things in response to two different error codes, they should be the same code.
Providing more than one success code. This is asking for subtle bugs.
Also, think very carefully about which APIs ought to be allowed to fail. Here are some things that should never fail:
Read-only data accessors, especially those that return scalar quantities, most especially those that return Booleans.
Destructors, in the most general sense. (This is a classic mistake in the UNIX kernel API: close and munmap should not be able to fail. Thankfully, at least _exit can't.)
There is a strong case that you should immediately call abort if malloc fails rather than trying to propagate it to your caller. (This is not true in C++ thanks to exceptions and RAII -- if you are so lucky as to be working on a C++ project that uses both of those properly.)
In closing: for an example of how to do just about everything wrong, look no further than XPCOM.
You return pointers to static const char [] objects. This is always the correct way to handle error strings. If you need them localized, you return pointers to read-only memory-mapped localization strings.
In C, if you don't have internationalization (I18N) or localization (L10N) to worry about, then pointers to constant data is a good way to supply error message strings. However, you often find that the error messages need some supporting information (such as the name of the file that could not be opened), which cannot really be handled by constant data.
With I18N/L10N to worry about, I'd recommend storing the fixed message strings for each language in an appropriately formatted file, and then using mmap() to 'read' the file into memory before you fork any threads. The area so mapped should then be treated as read-only (use PROT_READ in the call to mmap()).
This avoids complicated issues of memory management and avoids memory leaks.
Consider whether to provide a function that can be called to get the latest error. It can have a prototype such as:
int get_error(int errnum, char *buffer, size_t buflen);
I'm assuming that the error number is returned by some other function call; the library function then consults any threadsafe memory it has about the current thread and the last error condition returned to that thread, and formats an appropriate error message (possibly truncated) into the given buffer.
With C++, you can return (a reference to) a standard String from the error reporting mechanism; this means you can format the string to include the file name or other dynamic attributes. The code that collects the information will be responsible for releasing the string, which isn't (shouldn't be) a problem because of the destructors that C++ has. You might still want to use mmap() to load the format strings for the messags.
You do need to be careful about the files you load and, in particular, any strings used as format strings. (Also, if you are dealing with I18N/L10N, you need to worry about whether to use the 'n$ notation to allow for argument reordering; and you have to worry about different rules for different cultures/languages about the order in which the words of a sentence are presented.)
I guess you could use PWideChars, as Windows does. Its thread safe. What you need is that the calling app creates a PwideChar that the Dll will use to set an error. Then, the callling app needs to read that PWideChar and free its memory.
R. has a good answer (use static const char []), but if you are going to have various spoken languages, I like to use an Enum to define the error codes. That is better than some #define of a bunch of names to an int value.
return integers, don't set some global variable (like errno— even if it is potentially TLSed by an implementation); aking to Linux kernel's style of return -ENOENT;.
have a function similar to strerror that takes such an integer and returns a pointer to a const string. This function can transparently do I18N if needed, too, as gettext-returnable strings also remain constant over the lifetime of the translation database.
If you need to provide non-static error messages, then I recommend returning strings like this: error_code_t function(, char** err_msg). Then provide a function to free the error message: void free_error_message(char* err_msg). This way you hide how the error strings are allocated and freed. This is of course only worth implementing of your error strings are dynamic in nature, meaning that they convey more than just a translation of error codes.
Please havy oversight with mu formatting. I'm writing this on a cell phone...

Suggestions on error handling of Win32 C++ code: AtlThrow vs. STL exceptions

In writing Win32 C++ code, I'd appreciate some hints on how to handle errors of Win32 APIs.
In particular, in case of a failure of a Win32 function call (e.g. MapViewOfFile), is it better to:
use AtlThrowLastWin32
define a Win32Exception class derived from std::exception, with an added HRESULT data member to store the HRESULT corresponding to value returned by GetLastError?
In this latter case, I could use the what() method to return a detailed error string (e.g. "MapViewOfFile call failed in MyClass::DoSomething() method.").
What are the pros and cons of 1 vs. 2?
Is there any other better option that I am missing?
As a side note, if I'd like to localize the component I'm developing, how could I localize the exception what() string? I was thinking of building a table mapping the original English string returned by what() into a Unicode localized error string. Could anyone suggest a better approach?
Thanks much for your insights and suggestions.
AtlThrow isn't terribly useful, it throws CAtlException which merely wraps an error code. Having a MapViewOfFile fail is a truly exceptional problem with a low-level error code that doesn't tell you or your user much at all what actually went wrong. Handling the error is almost always impossible, it isn't likely that you can shrug it off and just not use a MMF. You'll have to log the error and terminate your program with a very generic error.
Getting very detailed in your error message is usually wasted effort. "MapViewOfFile call failed in MyClass::DoSomething() method" just doesn't mean anything at all to your user or her support staff. Great for you though, something to trace the error to. But you can easily automate this, without localization trouble, by using the __FILE__ and __LINE__ macros. All that you really need to match the error to the source code.
Keep the error message short and snappy. For Windows errors, you'll want to use FormatMessage() to let Windows generate the message. It will automatically be localized, the message text is standardized and googles well. Deriving from std::exception is okay. Use string resource IDs for custom messages so you can easily localize them. Solves the what() problem too.
You shouldn't use exceptions for error handling. Exceptions are exceptional. For C++ error handling, look at : System error support in C++0x

Error handling and polymorphism

I have an application with some bunch of code like this:
errCode = callMainSystem();
switch (errCode){
case FailErr: error("Err corresponding to val1\n");
case IgnoreErr: error("Err corresponding to val2\n");
...
...
default: error("Unknown error\n");
}
The values are enum constants. Will it make some sense to have something like:
// Error* callMainSystem()
... Some code
return FaileErr(); // or some other error
// handling code
Error* err = callMainSystem();
err->toString();
The Error class may be made singleton as it only has to print error messages.
What are the pros and cons of above methods,size is an important criteria as the application needs to be supported on embedded devices as well.
P.S: I don't want to use exception handling because of portability issues and associated overheads.
When you say:
I don't want to use exception handling
because of portability issues and
associated overheads.
There really aren't any, assuming an even moderately up-to-date compiler. All you are doing is reproducing in your code what the C++ compiler will do for you anyway.
IMHO polymorphism would be overkill here, as you don't actually need different behaviour, only use different data per error code. I would use a simple map<ErrorCode, string> instead to store the mappings from error codes to messages.
The polymorphic solution would require the extra overhead of creation and destruction of Error instances. I can't see how to make Error a singleton; however, you could implement it as a sort of typesafe enum like in Java (i.e. a fixed number of constant instances). However, hardwiring their behaviour (e.g. printing error messages to stderr) can make it awkward to unit test your code.