views:

259

answers:

2

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 ?

+1  A: 

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. :)

Cheers, V.

vladr
Just because "no body stops me" does not mean your suggestion is anywhere near elegent. Also I have said the following "I have written my own exception hierarchies against win32 and POSIX before" and finally I have mentioned portability as being a desirable feature as well. So this answer adds no value. Thanks though.
Hassan Syed
+1, Vlad. simple solution, gets the job done.
Paul Nathan
@Hassan Syed: The only thing in boost that comes close to this is `Boost::System` ( http://www.boost.org/doc/libs/1_42_0/libs/system/doc/index.html ), and that's not going to help you with iostreams.
Billy ONeal
I don't want to sound finicky, but while " **RE** Writing " uniform error handling for OS abstractions is indeed the norm, this is the **EXACT** thing my question **is aiming to address**. Rehashing the obvious --which has also been addressed in the quesstion -- is not a solution. I don't want to re-invent the wheel, I am asking if there is a modern robus solution to my problem.
Hassan Syed
Thank you billy (+1), I have known of its existence, I guess I will give the library a closer look.
Hassan Syed
Billy upon closer inspection, boost::system is indeed the **exact solution** to my question. If you create the answer I can accept it :D. I was avoiding it due to it not having tutorial style documentation :D
Hassan Syed
@Hassan, I fail to see what is inelegant about the solution, how `errno` is not portable (it is in fact your only portable choice), and what anyone other than you was supposed to make of your "I have written my own exception hierarchies". You can wrap and abstract it all you want, at the end of the day you *will* have to read `errno`.
vladr
Someone "WILL HAVE TO" read errno, that someone does not have to be me -- "All problems in computer science can be solved by another level of indirection", I don't want to provide this level of indirection, yet again. I hope We can all agree that reuse is good in software engineering ?
Hassan Syed
A: 

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.

Potatoswatter