How to define custom error codes in C(++) - c++

I'm desperately trying to define custom error codes in C(++).
As for the project I'm working on it's forbidden to use Exceptions and Signals and any other approach which could allocate dynamic memory.
I used the standard error codes for some methods which produce errors resembling those but for some methods the errors are to specific to be covered by the standard error codes the OS is providing.
I also searched for the error strings in my system but couldn't manage to find the error messages O_O Where are those defined anyway?
So I'm searching for any method which allows me to define a custom error code (e.g. 666) and the correspondig error message ("Satan declared an error!") which will be outputted using strerror.
Is this possible or do I have to meddle with some system related files?
In best regards,
ahnimuhs

If you declare an enum as a type, that can satisfy the domain where typesafety propagates.
Then you can offer a function to access the description as a char buffer (given a locale?, the current locale?).
class t_mon_io_error {
public:
enum t_type {
...
SatanDeclaredAnError = 666
...
};
static const char* Description(const t_type& pError) {
switch(pError) {
...
}

Some implementations of strerror(3) allow for user defined error codes and labels.
You have to provide a _user_strerror() function and define error codes after __ELASTERROR.

Related

What is the better way to use an error code in C++?

I'm a member of project which uses c++11. I'm not sure when I should use error code for return values. I found RVO in c++ works great even if string and struct data are returned directly. But if I use a return code, I cannot get the benefit of RVO and the code is a little redundant.
So every time I declare function, I couldn't decide which I should use for a return value. How should I keep a consistency of my code? Any advice will help me.
// return string
MyError getString(string& out);
string getString();
// return struct
MyError getStructData(MyStruct& out);
MyStruct getStructData();
Usually, using exceptions instead of error codes is the preferred alternative in C++. This has several reasons:
As you already observed, using error codes as return values prevents you from using the return values for something more "natural"
Global error codes, are not threadsafe and have several other problems
Error codes can be ignored, exceptions can not
Error codes have to be evaluated after every function call that could possibly fail, so you have to litter your code with error handling logic
Exceptions can be thrown and passed several layers up in the call stack without extra handling
Of course there are environments where exceptions are not available, often due to platform restrictions, e.g. in embedded programming. In those cases error codes are the only option.
However, if you use error codes, be consistent with how you pass them. The most appealing use of error codes I have seen that does not occupy the return value spot and is still thread safe was passign a reference to a context object in each and every function. The context object would have global or per-thread information, including error codes for the last functions.

C++11 (or Boost) system_error strategy

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.

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.

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.