Getting meaningful error messages from fstream's in C++ - c++

What is the best way to get meaningful file access error messages, in a portable way from std::fstreams ? The primitiveness of badbits and failbits is getting to be bit annoying. I have written my own exception hierarchies against win32 and POSIX before, and that was far more flexible than the way the STL does it.
I am getting "basic::ios_clear" as an error message from the what method of a downcasted catch (std::exception) of a fstream which has exceptions enabled. This doesn't mean much to me, although I do know what the problem is I'd like my program to be a tad more informative so that when I start deployment a few months later my life will be easier.
Is there anything in Boost to extract meaningful messages out of the fstream's implementation cross platform and cross STL implementation ?

Nobody stops you from also checking errno/strerror (e.g. in your exception handler) for a more specific reason for failure.
UPDATE -- regarding portability
Incidentally, IIRC Visual Studio's fstream implementation calls the _open/_read/_write/etc. CRT methods, which set errno. Microsoft makes no guarantee about GetLastError still containing the correct value after the CRT methods return. Idem for the cygwin, mingw etc. implementations, which set errno with no claims or guarantees about GetLastError.
So I stand by my claim that all you need, can, and therefore want to do is check errno.
Now, given all of the above, if you still want to complicate your life and overengineer by using Boost::System instead of simply calling strerror then I guess my definition and your definition of elegance and simplicity are not the same. :)

What information do you want? badbit indicates an I/O error. eofbit indicates eof. failbit indicates a parse error.
To eliminate one solution, anyway, I don't think you can override the native-type input functions because of ADL. You could implement operator>>(istream, input_safe_int) where input_safe_int is constructed from int&. Put a try block inside, etc.

I've had luck catching the std::ios_base::failure and then re-raising a std::system_error using errno:
terminate called after throwing an instance of 'std::system_error'
what(): broken/path: No such file or directory
#include <fstream>
int main() {
const std::string filename{ "broken/path" };
try {
std::ifstream file{ filename };
file.exceptions(std::ios::failbit); // std::ios_base_failure is thrown here
} catch (std::ios_base::failure&) {
throw std::system_error{ errno, std::generic_category(), filename };
}
}
This works on UNIX and Windows because "All errno values are … UNIX-compatible" (source).

Related

What is the purpose of std::exception::what()?

I can only think of the following situations where std::exception::what() is used:
For debug purpose. In my Visual Studio to see e.what() I have to manually add it to the watch list. Isn't it better to have a member std::string (so the debugger directly shows it in the object inspector), and only include it in non-NDEBUG builds? At least they should disable what() in NDEBUG builds.
Output it, e.g. MessageBox(e.what()) or cout << e.what(). As far as I know these messages are useless for many users. For example when I try to rename a file that doesn't exist:
boost::filesystem::rename: 系统找不到指定的文件。: "D:\MyDesktop\4", "D:\MyDesktop\5"
(The Chinese words means "The system cannot find the file specified.") How can the users decrypt the mixed things? Also, it is a const char* instead of something like const platform_char*, which may have unicode problems in Windows.
Extract data from it, e.g. std::regex_match(e.what()...). I think it's a terrible idea that shows design flaws.
So where should I use std::exception::what()? Is it useless?
A programmer is supposed to derive a class from std::exception and taylor what() to the specific requirements. Then it can be very useful.
It's also useful to report something back (e.g. in plain text for logging), which is why the standard mandates a concrete std::exception::what() rather than a pure virtual function.
what() is generic in the sense that it means what you want it to mean for your own exception classes. In many cases it is used only for logging, but in other cases it may provide information that can be used to recover from an exceptional situation.
So where should I use std::exception::what()? Is it useless?
The error message of std::exception is a char* because it's supposed to be an as-simple-as-possible user-facing diagnostics message giving details on the error.
For boost::system_error (and std::system_error), you can also get the OS-level error code (for which the user-friendly message is "file not found").
Valid uses:
if you want to identify the error type, catch the specialization std::system_error or boost::system_error and perform a switch/if on the code() function (i.e. instead of running a regex on the message).
if you want to display an explanation of the error for diagnostics (logging) or user friendliness (to console/GUI) just display the error message (what()).
std::exception is a base class (i.e. it has a virtual destructor). If you implement your own exception classes, follow the same pattern as std::system_error: use an error code to easily identify an error, and create your exception's base class (std::exception, std::runtime_error or std::logic_error usually) with a text message depending on the error type.
Ultimately, the type of the error message is char* instead of std::string, wstring or your-platform-specific-char-type because it sacrifices flexibility for reliability: with a char* everybody knows how to use it, that it has no encoding (except ASCII), that it's null terminated and once allocated, it does not fail (it doesn't generate new exceptions).
Using something that could fail (in any way) when constructing an exception would be disastrous: you would fail while creating/using a diagnostics message of your error handling code.
This means you could either not throw the exception (and your application will remain in an invalid state), or throw an exception while creating an exception instance (you really don't want that as it would discard the exception you wanted to throw (hide errors) or throw an exception with a missing or corrupted error code (which could waste months of development time in various projects to track down the wrong error).
Consider this example (unnecessarily complicated, but it makes a point):
int * p = new(nothrow) int(10); // I want to throw a complicated
// string message exception
if(nullptr == p)
throw complicated_exception(std::string("error message here"));
The throw line will presumably fail: the application has so little memory available that it won't even allocate an int*, let alone a string. The result of this code is that in low memory conditions I will still get a std::out_of_memory error - one generated by std::string constructor.
std::exception is a good implementation: it provides a minimal extendable interface with a good management/restriction of failure points and it gives a good interface for extensions (such as std::system_error).

Throw runtime warnings in C++

I started using exceptions some weeks ago and now I wonder if there is a way to just throw a warning. This warning shouldn't force the application to exit if it isn't caught. I will give you an example in what situation I would like to use that.
There is a system that appends properties to unique ids. When I somehow try to add a property to a not yet existing id, the system should create that id internally for me, add the property to it afterwards and return the result. Of course this can't be done quietly. But since the application could stay running, I do not want to throw an exception.
How can I notify that something wasn't quite correct, but the system runs on?
Who do you want to notify? The end-user? In which case, just write a suitable message to cerr. Or better, write a wrapper function (e.g. LOG_WARNING()) to do it in a controlled manner. Or better still, use a logging framework.
But since the application could stay running, I do not want to throw an exception.
Note that an exception doesn't have to result in the application terminating. You can catch an exception higher up the stack, and handle the situation appropriately.
No, that's not possible. You can only throw and catch exceptions. If you want to be cheeky you could do
class warning : public std::exception
{
public:
warning(const std::string& msg) {}
const char* what() { return msg.c_str(); } //message of warning
private:
std::string msg;
};
Then you can:
throw warning("this is a warning");
This could be an artificially made up warning system if you want.
While there's no throwing a warning. I believe the functionality you're looking for is available from errno
You can set it to any of the standard errors or make up your own error codes. (Please document them well though.)
This could be useful if your library is meant to be used by other developers. An example of when this might be useful is with a JSON parser. JSON supports arbitrarily large numbers with arbitrary accuracy. So if internally your parser uses doubles to represent numbers if it encountered a number that it couldn't represent then it could round the number to the nearest representable number the set errno=EDOM; (argument out of range) that way, it leaves the decision up to the developers as to whether the rounding will matter. If you want to be super nice you could even add in a way to retrieve the locations of the rounds possibly even with the original text.
All of that said, this should only be used in situations where:
the warning really can be bypassed completely in some scenarios
the root source of the warning is input to the library you're writing
the in some situations the consumer of the library might care about the warning but most of the time wouldn't.
there's not a more suitable way to return the information (like a status passed by reference with an overload that doesn't require the status)
Just print a message to stderr or to your logs.

Determining the exact reason for not opening of file

The problem is that std::fstream doesn't throw exceptions by default but rather sets bits that can then be examined. Apparently, it can then be made to throw exceptions (I think) by using the exceptions function as explained here -- see e.g. c++ reference page
But what if, for example, the write permissions of the file mean that the file cannot be written to? This would mean that when I try and do
ofstream file("file", ios::out);
a failure would result. But how can it be determined if it failed for the precise reason that the uid didn't have write permissions? I guess what I am looking for is some mechanism that will tell me precisely this e.g. it might show "File cannot be written to because...". I do not want to have to check file permissions because there are so many reasons why write failure could occur (hard-drive failures/corruption etc.). It would be better if it would just tell me exactly why it failed.
Does anybody know if such an error checking system exists for iostreams (ostreams in particular)? (Maybe in boost?)
You can try to check errno and perhaps convert it to a human-readable form with strerror.
The standard doesn't guarantee anything about applicability of errno to I/O failures, but in practice it should work.

Correct Exceptions in C++

I am just learning how to handle errors in my C++ code. I wrote this example that looks for a text file called some file, and if its not found will throw an exception.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int array[90];
try
{
ifstream file;
file.open("somefile.txt");
if(!file.good())
throw 56;
}
catch(int e)
{
cout<<"Error number "<<e<<endl;
}
return 0;
}
Now I have two questions. First I would like to know if I am using Exceptions correctly. Second, (assuming the first is true) what is the benefit to using them vs an If else statement?
"Correctly" is a value judgment, but (unlike other classes) there's a major benefit from exceptions classes being a monolithic hierarchy, so I'd generally advise throwing something derived from std::exception, not simply an int.
Second, it's open to question whether an incorrect file name is sufficiently unexpected to qualify as a good reason to throw an exception at all.
As to benefits vs. an if/else statement: there are a couple. First, exceptions let you segregate the code that deals with errors, so the main idea and readability of the code don't get lost in a maze of error handling. Second, when you have several layers of code between throwing and catching the exception, the code that throws the exception may not know how it should really be handled. Your code, for example, uses std::cout to report the problem -- but most such code would report errors on std::cerr instead. You can change from one to the other without any change to the code that tried to open the file (which might be deep in a library, and have no clue of which should be used for this application -- and might be used in an application where both are wrong, and MessageBox was preferred).
First I would like to know if I am using Exceptions correctly.
Yes, though generally you want your exceptions to derive from std::exception.
Second, (assuming the first is true) what is the benefit to using them vs an If else statement?
For the given example, nothing. The benefit of exceptions comes when you have
many deep nested functions, like this.
#include <stdexcept>
#include <iostream>
#include <string>
void anErrorFunc(const std::string& x)
{
ifstream file;
file.open(x);
if (!file)
throw std::runtime_error("Could not open file");
}
void someOtherFunction(const std::string& y)
{
//Do stuff
anErrorFunc(y);
//Do other stuff
}
int main()
{
try {
someOtherFunction("somefile.txt");
} catch (std::exception &ex) {
std::cout << "Ouch! That hurts, because: "
<< ex.what() << "!\n";
}
}
Note that the exception will be caught in main(), and someOtherFunction
does not have to worry about dealing with passing through failure return codes.
Well, you are using exception correctly in that there is nothing wrong with your code. That said, typically we do not throw primitive types around (even though you can). It is generally a better idea to throw an object that derives from std::exception, and even better to throw an std::exception that is also a boost::exception.
When things are very simple and the handling code and the throwing code are in the same function, then there really is no reason to use exceptions instead of if statements (and, indeed, it would be faster and more efficient to use if...else in that particular case). However, in most situations, the point where the error is discovered and you need to report it is far removed from the logic where the error is to be handled. In many cases the error-recovery logic is specific to the application in question and the logic where the error is discovered cannot make a sensible choice about how to recover from the error, hence the need to throw.
Another benefit of exception handling is that the type of the exception can be used to convey the type of error that occurred. Usually the types in exception hierarchies are much more meaningful than those error codes that end up being used in C code. Also, you cannot ignore an exception as easily as you can ignore an error code; while you can ignore an exception, it will cause the program to die a horrible death. By contrast, if a C function returns an error status code, and you ignore it, it's possible to continue executing and get silently wrong results... in that sense, the use of exceptions is much safer than using error codes.
You may also be interested in reading about exceptions and error handling from the C++ FAQ Lite.
You are not using exceptions correctly. Your code has a much simpler equivalent, without exceptions, which provides the same behaviour.
Exceptions are for when you can't test the results of a function call with other methods. In this case you can, so you shouldn't use exceptions.
As a corollary, you shouldn't throw and catch the exception in the same function body - just do whatever you want to do instead of throwing it.
Syntactically speaking, your code is correct. Idiomatically speaking, maybe not so much -- or at least this depends on the context. When a file can't open then we might do our handling right there inside that if( !file.good() ) if it's perfectly common and possible to happen. For example, if the user asks to open a file in a text editor then it's perfectly plausible and common that the file doesn't exist. On the other hand, if the editor can't find the spelling corpus file then that means something is (arguably) terribly wrong. The program wasn't probably installed, or the user messed around with that file -- anything is possible.
In C++ we use exceptions for exceptional cases. That is, cases that are really not meant to happen and that we don't "accept" to happen. This is as opposed to a user file not opening, or an invalid user input, or no internet connection: these are all examples of perfectly valid things happening, common situations, things we expect to happen sooner or later in a program's run. They aren't exceptional.
Now, what are the benefits of using exceptions compared to conditionals? Allow me to extend this question to any other jump (goto) mechanism: returns as well as conditionals. Exceptions are more expressive if that's what you want to say: if you are dealing with an exceptional case then use exceptions. Exceptions also get more done than plain conditionals, in an analogous way to that of virtual functions getting more done than conditionals. The right code-block will be executed depending on the exception, but also the right scope will handle the exception depending on the handlers.
There are other advantages to exceptions compared with conditionals: exceptions separate error-handling from other code. They allow associating arbitrary data and actions with an error state. They allow communicating success states (via a return) as well as error state (via a throw). And the list goes on...
Technically speaking and at the lowest level exceptions are a sophisticated jump mechanism. Back in the butterfly-days people invented the if conditional as a somewhat-sophisticated goto in order to enhance expressiveness (because a goto can be used for anything really) and to reduce programmer errors. The looping constructs such as the C for loop are also in essence a sophisticated jump with sparkles and rainbow colours, again for reducing errors and enhancing expressiveness. C++ introduced its new casting operators for the same reasons.
So there: exceptions aren't magic, just something somewhat new in the scene compared to conditionals and loops. Don't use them when you don't mean to, just like you don't use a loop when you really mean to use a conditional.
Syntactically what you're doing is right. Style-wise, as others have noted, you should be throwing something descended from std::exception.
As to part two of your question, I'd like to go into more detail on that.
The whole point of exceptions is to separate policy from implementation. As Billy ONeal said, you get no benefit at all from using exceptions within the same function that an if statement wouldn't make better. You need to be deeply nested in function calls for it to make sense.
In most code, your high level code has enough information and context to know what to do about errors, but no mechanism to detect them. Your low level code can detect the errors but has none of the information needed to deal with them.
The traditional means of coping with this -- returning error codes -- has a few problems:
It clutters up the code with error handling code to the point that the actual logic is obfuscated.
It relies on programmers not being lazy and checking EVERY error code return, an often foolhardy assumption. (C programmers, be honest here: when was the last time you checked the return value of printf?)
It adds the overhead of error checking and handling to EVERY function call whether there's an error or not.
Exceptions solve these issues (with varying degrees of success).
Exceptions solve #1 by only having exception-related code at the point of detection and at the point of handling. Intervening functions don't get cluttered with handling for obscure errors that they themselves have no interest in nor capability of dealing with.
They solve #2 by forcing handling. You can't ignore an exception. You have to take action on them. (Lazy programmers can still catch all exceptions and then ignore them, but here their crippling inability to program is now highlighted for all to see.)
They solve #3 (when not naively implemented) by having near-zero costs when not used, albeit often at a very, very high cost when actually used.
This is not to say that exceptions are the end-all/be-all of error handling. The disadvantages:
Exceptions are usually very costly when used. They have to be eschewed, despite their advantages, if performance is paramount.
Exceptions lead to very opaque code at times. They are non-local transfers of control -- effectively slightly safer versions of goto statements, but across functions. An exception can transfer control from hundreds of layers deep in your code in source files not even slightly related to the ones you're working on (and, in fact, quite possibly not even accessible to you). This kind of "spooky action at a distance" can make code very difficult to figure out.
"Checked exceptions" can actually be worse for noise generation than the old-style if handling. They tend to be more verbose, you see, than if or switch statements and the fact that you must handle checked exceptions for the code to even compile makes them a liability to many situations.
Because of their often high cost of use, carelessly using them for all error handling can make your code slow and bloated.

Finding out the source of an exception in C++ after it is caught?

I'm looking for an answer in MS VC++.
When debugging a large C++ application, which unfortunately has a very extensive usage of C++ exceptions. Sometimes I catch an exception a little later than I actually want.
Example in pseudo code:
FunctionB()
{
...
throw e;
...
}
FunctionA()
{
...
FunctionB()
...
}
try
{
Function A()
}
catch(e)
{
(<--- breakpoint)
...
}
I can catch the exception with a breakpoint when debugging. But I can't trace back if the exception occurred in FunctionA() or FunctionB(), or some other function. (Assuming extensive exception use and a huge version of the above example).
One solution to my problem is to determine and save the call stack in the exception constructor (i.e. before it is caught). But this would require me to derive all exceptions from this base exception class. It would also require a lot of code, and perhaps slow down my program.
Is there an easier way that requires less work? Without having to change my large code base?
Are there better solutions to this problem in other languages?
You pointed to a breakpoint in the code. Since you are in the debugger, you could set a breakpoint on the constructor of the exception class, or set Visual Studio debugger to break on all thrown exceptions (Debug->Exceptions Click on C++ exceptions, select thrown and uncaught options)
If you are just interested in where the exception came from, you could just write a simple macro like
#define throwException(message) \
{ \
std::ostringstream oss; \
oss << __FILE __ << " " << __LINE__ << " " \
<< __FUNC__ << " " << message; \
throw std::exception(oss.str().c_str()); \
}
which will add the file name, line number and function name to the exception text (if the compiler provides the respective macros).
Then throw exceptions using
throwException("An unknown enum value has been passed!");
There's an excellent book written by John Robbins which tackles many difficult debugging questions. The book is called Debugging Applications for Microsoft .NET and Microsoft Windows. Despite the title, the book contains a host of information about debugging native C++ applications.
In this book, there is a lengthy section all about how to get the call stack for exceptions that are thrown. If I remember correctly, some of his advice involves using structured exception handling (SEH) instead of (or in addition to) C++ exceptions. I really cannot recommend the book highly enough.
Put a breakpoint in the exception object constructor. You'll get your breakpoint before the exception is thrown.
There is no way to find out the source of an exception after it's caught, unless you include that information when it is thrown. By the time you catch the exception, the stack is already unwound, and there's no way to reconstruct the stack's previous state.
Your suggestion to include the stack trace in the constructor is your best bet. Yes, it costs time during construction, but you probably shouldn't be throwing exceptions often enough that this is a concern. Making all of your exceptions inherit from a new base may also be more than you need. You could simply have the relevant exceptions inherit (thank you, multiple inheritance), and have a separate catch for those.
You can use the StackTrace64 function to build the trace (I believe there are other ways as well). Check out this article for example code.
Here's how I do it in C++ using GCC libraries:
#include <execinfo.h> // Backtrace
#include <cxxabi.h> // Demangling
vector<Str> backtrace(size_t numskip) {
vector<Str> result;
std::vector<void*> bt(100);
bt.resize(backtrace(&(*bt.begin()), bt.size()));
char **btsyms = backtrace_symbols(&(*bt.begin()), bt.size());
if (btsyms) {
for (size_t i = numskip; i < bt.size(); i++) {
Aiss in(btsyms[i]);
int idx = 0; Astr nt, addr, mangled;
in >> idx >> nt >> addr >> mangled;
if (mangled == "start") break;
int status = 0;
char *demangled = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
Str frame = (status==0) ? Str(demangled, demangled+strlen(demangled)) :
Str(mangled.begin(), mangled.end());
result.push_back(frame);
free(demangled);
}
free(btsyms);
}
return result;
}
Your exception's constructor can simply call this function and store away the stack trace. It takes the param numskip because I like to slice off the exception's constructor from my stack traces.
There's no standard way to do this.
Further, the call stack must typically be recorded at the time of the exception being thrown; once it has been caught the stack has unrolled, so you no longer know what was going on at the point of being thrown.
In VC++ on Win32/Win64, you might get usable-enough results by recording the value from the compiler intrinsic _ReturnAddress() and ensuring that your exception class constructor is __declspec(noinline). In conjunction with the debug symbol library, I think you could probably get the function name (and line number, if your .pdb contains it) that corresponds to the return address using SymGetLineFromAddr64.
In native code you can get a shot at walking the callstack by installing a Vectored Exception handler. VC++ implements C++ exceptions on top of SEH exceptions and a vectored exception handler is given first shot before any frame based handlers. However be really careful, problems introduced by vectored exception handling can be difficult to diagnose.
Also Mike Stall has some warnings about using it in an app that has managed code. Finally, read Matt Pietrek's article and make sure you understand SEH and vectored exception handling before you try this. (Nothing feels quite so bad as tracking down a critical problem to code you added help track down critical problems.)
I believe MSDev allows you to set break points when an exception is thrown.
Alternatively put the break point on the constructor of your exception object.
If you're debugging from the IDE, go to Debug->Exceptions, click Thrown for C++ exceptions.
Other languages? Well, in Java you call e.printStackTrace(); It doesn't get much simpler than that.
In case anyone is interested, a co-worker replied to this question to me via email:
Artem wrote:
There is a flag to MiniDumpWriteDump() that can do better crash dumps that will allow seeing full program state, with all global variables, etc. As for call stacks, I doubt they can be better because of optimizations... unless you turn (maybe some) optimizations off.
Also, I think disabling inline functions and whole program optimization will help quite a lot.
In fact, there are many dump types, maybe you could choose one small enough but still having more info
http://msdn.microsoft.com/en-us/library/ms680519(VS.85).aspx
Those types won't help with call stack though, they only affect the amount of variables you'll be able to see.
I noticed some of those dump types aren't supported in dbghelp.dll version 5.1 that we use. We could update it to the newest, 6.9 version though, I've just checked the EULA for MS Debugging Tools -- the newest dbghelp.dll is still ok to redistribute.
I use my own exceptions. You can handle them quite simple - also they contain text. I use the format:
throw Exception( "comms::serial::serial( )", "Something failed!" );
Also I have a second exception format:
throw Exception( "comms::serial::serial( )", ::GetLastError( ) );
Which is then converted from a DWORD value to the actual message using FormatMessage. Using the where/what format will show you what happened and in what function.
By now, it has been 11 years since this question was asked and today, we can solve this problem using only standard C++11, i.e. cross-platform and without the need for a debugger or cumbersome logging.
You can trace the call stack that led to an exception
Use std::nested_exception and std::throw_with_nested
This won't give you a stack unwind, but in my opinion the next best thing.
It is described on StackOverflow here and here, how you can get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging, by simply writing a proper exception handler which will rethrow nested exceptions.
It will, however, require that you insert try/catch statements at the functions you wish to trace (i.e. functions without this will not appear in your trace).
You could automate this with macros, reducing the amount of code you have to write/change.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"