Do I need to implement a FileNotFoundError exception? - c++

I've a class called TFile, and I can't (don't want to) modify it. It doesn't throw exception if the input/output file is not found but I can check the iternal status using the method IsZombie. Now, I've implemented a very simple exception:
class FileNotFoundError : public std::runtime_error
{
public :
FileNotFoundError(const std::string & file_name="")
: runtime_error("cannot find file " + file_name), filename(file_name) {};
string filename;
~FileNotFoundError() throw() {};
};
and I use it as:
f = new TFile(total.c_str(), "RECREATE") ;
if (f->IsZombie())
{
throw FileNotFoundError(total);
}
is there a better way to implement this exception, I mean: is it userful to throw a standard exception as ifstream::failure instead of my custom exception?

There is no std exception that gives you a highly selective way to catch a 'file not found' error condition. So, yes, if you want to signal that condition with an exception and you want to allow the client code to do something meaningful then you need to create your own class for that.
There is however also a reason why that exception doesn't already exist, even though it is by far the most common mishap. It's kinda normal that a file isn't there when you expect it to be. Your program is not in control of the file system. Or maybe the user typed the file name wrong, something like that. It isn't really exceptional that this goes wrong. Don't use exceptions for non-exceptional cases.
This is a mixed message. Do use it when the client code had a reasonable way to check for itself that the file should exist and continuing program execution without that resource is unlikely.

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

C++ Project with well designed exception mechanism

Does anyone know a opensource c++ application with a well designed/robust exception mechanism so I can get some inspiration? Most code/examples I see do questionable things like:
Throw objects with a message string as argument. Seems wrong because it marks the exception as fatal, a error message wich can be displayed to the user higher up leaves little room for client code trying to handle the exception. Even if the exception is fatal, things like diffirent locales (languages) makes formatting a message at the point of throw seem like a bad idea to me.
Use tons of different exception classes derived from a base exception class. Just feels wrong introducing a new class/type for every single thing that can go wrong (open file, read file, write file, create thread, etc...). Catching all unhandled exceptions at the highest level using the base type loses type information required to display meaningfull error messages.
Use one exception class derived from a base exception class for every component/library and give it a error code as argument to indicate the exact error. Catching with base type results in ambiguity. (Whose error code "3" did we catch? )...
Some pointers in the right direction would be welcome.
To address all three of these, I found that the best for me is to throw my own custom exception that's derived from std::runtime_error. Like this:
#include <exception>
class ChrisAException : public std::runtime_error
{
/// constructor only which passes message to base class
ChrisAException(std::string msg)
: std::runtime_error(msg)
{
}
}
It allows accepting a string, which I always put in something like the following format (assuming x negative was not a valid input and meant something calling it was in error):
#include "ChrisAException.h"
void myfunction(int x)
{
if(x < 0)
{
throw ChrisAException("myfunction(): input was negative!");
}
// rest of your function
}
For this one, keep in mind that the strings in these exceptions are more for the programmer than the end user. It's the programmer of the interface's job to display something meaningful in the locale when there's a failure. The strings in the exception can either be logged or seen at debug time (preferable!)
This way you can ultimately catch it with:
try
{
// high level code ultimately calling myfunction
}
catch(ChrisAException &cae)
{
// then log cae.what()
}
catch(std::runtime_error &e)
{
// this will also catch ChrisAException's if the above block wasn't there
}
catch(...)
{
// caught something unknown
}
I personally don't like deriving too many types of exceptions, or giving an error code. I let the string message do the reporting.
In general, I use C++ exceptions to mean "something went wrong with the program" and not to handle normal use cases. Thus, for me, a thrown exception during the algorithm execution either means "flag the user that something went wrong" or "don't tell the user" (depending on how critical that code was to what they were doing) but certainly log it and let the programmers know somehow.
I don't use C++ exceptions to handle cases that aren't essentially programming errors, e.g., some kind of incorrect logic or something being called wrong. For example, I wouldn't use C++ exceptions to handle normal program situations like an empty DVD not being in the drive for a DVD writing program. For that, I'd have explicit return code that allows the user to know whether an empty DVD was there (maybe with a dialog etc.)
Keep in mind that part of C++ exception handling is to unwind the stack up to a try-catch block. To me that means, abort what's going on in the program and clean up the stack. In the case of something like my DVD example, you shouldn't really want to unwind much of the stack. It wasn't catastrophic. You should simply let the user know and then let them try again.
But again, this is my preferred way of using C++ exceptions, based on experience and my reading. I'm open to opinions otherwise.
edit: Changed std::exception to std::runtime_error based on commenter advice.

where to check for the error and how

I have a code design question.
My question is where should I place my user error handling code and what method should I use.
The situation is this, my user should provide a file name to a function, this function then tries to open the file and manipulate it. Should the file not exist I would like to notify the user and try again with a newly inputted file name. As I understand std exception handling is not a suitable solution for this case.
Now I believe I have a couple of options; check the file exists before calling the function,
check whether it exists within the function and return a true false to indicate whether it was successful, or check whether it exists within the file if not calling a function which prints the message and allows the name to be changed before returning to the original function.
Which of these methods is preferred and why, is there a better alternative/lib functionality I should be using.
Thanks in advance and sorry if the question is inconsequential but I like to try and get these things right.
Usually, you should try to open the file once you've got the filename, and loop if that fails. And the function should take an std::istream&, and not the filename. At least in the small scenario you show. Alternatively, the function can take the filename, and return an error code indicating whether it was unable to open the file or not. And there are cases (not very frequent, but they do exist) where the alternatives to using an exception have even more disadvantages, so the exception would be the most appropriate solution.
I wouldn't disregard exceptions that easily and say that they are not suitable. It just depends on the overall design - e.g. whether your client has exception handling enabled or not. You can build your exception class hierarchy and have let's say CFileException (inherited from std::exception) and then CFileNotFoundException, CFileAccessDeniedException...etc....inherited from it. If your client is happy to handle this type of exceptions - use them! You can pass more information about the error within the exception object than in the error code plus your client can decide where will that exception be handled.
The other solution is to return different error codes for different errors. Don't just return true/false - it will not give much information to the client (why did function fail). Client will need to test error code and produce message (error description, error cause) to the user accordingly. If you use exception instead, that message could be created in the function that failed - which is the context that contains more information about the error and its nature and so can create more descriptive message.
Regarding the breaking your function into smaller ones: you said "function then tries to open the file and manipulate it" so it would be worth having two separate functions - one which opens file and another which process it. The same rules for exception/errors apply - if opening file fails, exception will be thrown and the second would not be entered.
If you need specific input for a function, you should always check the arguments inside of the function if unexpected arguments will result in unexpected behavior, except your trying to build a high performance application. That's what std::invalid_argument in <stdexcept> is for.
Of course you should always try to ensure that the arguments you provide to your procedures are correct. But it doesn't harm you if your function can tell you that something is currently going wrong. Since your program can't read std::cout you have to stick to exceptions or return error codes.
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <string>
void myFunction(const std::string& inputFileName){
std::ifstream myFile(inputFileName.c_str());
if(!myFile.good())
throw std::invalid_argument("The file does not exist!\n");
/* other operations */
}
int main(){
std::string userInput;
std::cin >> userInput;
while(userInput != "quit"){
try{
myFunction(userInput);
}catch(const std::invalid_argument& e){
std::cout << e.what();
}
std::cin >> userInput;
}
return 0;
}
/* this code is just a small example and could be improved */

Handling C++ exception thrown in function exported to QtScript

I am using the Qt script engine in my application as an alternative way for the user to access its functionality. As such, I export some C++ classes to the Qt ScriptEngine, that will serve as the interface to the application. The problem is, these C++ classes can throw exceptions.
I have a "ScriptInterface" class running on its own thread, listening for requests to process scripts. So when I evaluate a user's script, I have a try/catch block around it to handle exceptions, and print the error to the console in the application.
...
try {
m_engine->evaluate(script, name);
}
catch (Exception const& e) {
// deal with it
}
catch (...) {
// scary message
}
This works perfectly in windows... but doesn't work in linux- the program terminates with this message:
terminate called after throwing an instance of 'Basilisk::InvalidArgumentException'
what(): N8Basilisk24InvalidArgumentExceptionE
Aborted
I had a hunch that it was because the exceptions bubbled up to the event handler (since the script engine uses signals to call the functions in my exported classes), so I reimplemented QApplication::notify, to handle exceptions there, but they weren't caught.
My question is, am I doing something fundamentally wrong? Also, as an alternative, is it possible to explicitly throw script exceptions from within my C++ classes?
Thanks in advance
EDIT: fixed the description to include the catch(...) statement.
UPDATE (SOLUTION): I "fixed" this problem by following a strategy similar to the one outlined in the accepted answer. Although I haven't gone to the source of why the exceptions don't get caught on linux (my suspicion now, is that m_engine->evaluate spawn a seperate thread on linux), but I have started using the intended way of exception throwing in Qt Scripts, and that is QScriptContext::throwError().
In cases where my function would look like this: (random example)
void SomeClass::doStuff(unsigned int argument) {
if (argument != 42) {
throw InvalidArgumentException(
"Not the answer to Life, the Universe and Everything.");
}
// function that is not part of the scripting environment,
// and can throw a C++ exception
dangerousFunction(argument);
}
It is now this: (pay particular attention to the return type)
QScriptValue SomeClass::doStuff(unsigned int argument) {
if (argument != 42) {
// assuming m_engine points to an instance of
// QScriptEngine that will be calling this function
return m_engine->currentContext()->throwError(QScriptContext::SyntaxError,
"Not the answer to Life, the Universe and Everything.");
}
try {
// function that is not part of the scripting environment,
// and can throw a C++ exception
dangerousFunction(argument);
} catch (ExpectedException const& e) {
return m_engine->currentContext()->throwError(QScriptContext::UnknownError,
e.message());
}
// if no errors returned, return an invalid QScriptValue,
// equivalent to void
return QScriptValue();
}
So where does one deal with these script errors? After the call to QScriptEngine::evaluate() you can check whether there are any uncaught exceptions, with QScriptEngine::hasUncaughtException(), obtain the error object with uncaughtException(), and now you have the message, the trace, and line number in the script where the error occured!
Hope this helps someone out!
I ran into a similar type of problem when trying to use SWIG with Python to wrap C++ libraries. Eventually what happened was that I made a stub for all the wrapped classes which caught the exception and failed quietly. Luckily I had the luxury of wrapping functionality which only passed container classes and state pattern objects, so I could easily check if something was amiss. May I suggest the same for you?
Wrap the functions you want with another function, same interface except the return value.
Create an object that contains not only the requested return type but also an error indicator.
Have the script make sure to check for the exceptions.
And yes, it's very possible for a script engine to throw C++ exceptions if you've given it access to an exception factory (a class whose sole purpose is to throw C++ exceptions.)
Run your program under a debugger and place a breakpoint inside your runtime library's terminate() function. That way you'll stop on terminate() in the debugger and by inspecting the call stack you will then see from where terminate() was called.

C++ exception handling and error reporting idioms

In C++, RAII is often advocated as a superior approach to exception handling: if an exception is thrown, the stack is unwound, all the destructors are called and resources are cleaned up.
However, this presents a problem with error reporting. Say a very generic function fails, the stack is unwound to the top level and all I see in the logs would be:
Couldn't read from socket: connection reset by peer.
...or any equally generic message. This doesn't say much about the context from which the exception is thrown. Especially if I'm running something like an event queue processing loop.
Of course I could wrap every call to socket reads with a try/catch block, catch the exception, construct a new one with more detailed context information and re-throw it, but it defeats the purpose of having RAII, and is slowly but surely becoming worse than handling return error codes.
What's a better way for detailed for error reporting in standard C++? I'm also open to suggestions involving Boost.
As James McNellis suggested here, there is a really neat trick involving a guard object and the std::uncaught_exception facility.
The idea is to write code like this:
void function(int a, int b)
{
STACK_TRACE("function") << "a: " << a << ", b: " << b;
// do anything
}
And have the message logged only in case an exception is actually thrown.
The class is very simple:
class StackTrace: boost::noncopyable // doesn't make sense to copy it
{
public:
StackTrace(): mStream() {}
~StackTrace()
{
if (std::uncaught_exception())
{
std::cout << mStream.str() << '\n';
}
}
std::ostream& set(char const* function, char const* file, unsigned int line)
{
return mStream << file << "#" << line << " - " << function << " - ";
}
private:
std::ostringstream mStream;
};
#define STACK_TRACE(func) \
StackTrace ReallyUnwieldyName; \
ReallyUnwieldyName.set(func, __FILE__, __LINE__)
One can use __PRETTY_FUNC__ or equivalent to avoid naming the function, but I have found in practice that it was too mangled / verbose for my own taste.
Note that you need a named object if you wish it to live till the end of the scope, which is the purpose here. We could think of tricky ways to generate a unique identifier, but I have never needed it, even when protecting narrower scope within a function, the rules of name hiding play in our favor.
If you combine this with an ExceptionManager (something where exceptions thrown register themselves), then you can get a reference to the latest exception and in case of logging you can rather decide to setup your stack within the exception itself. So that it's printed by what and ignored if the exception is discarded.
This is a matter of taste.
Note that in the presence of ExceptionManager you must remain aware that not all exceptions can be retrieved with it --> only the ones you have crafted yourself. As such you still need a measure of protection against std::out_of_range and 3rd party exceptions.
Say a very generic function fails, the stack is unwound to the top level and all I see in the logs would be [...]
What's a better way for detailed for error reporting in standard C++?
Error handling isn't local to a class or library - it is a application level concern.
Best I can answer you question is that the error reporting should be always implemented by looking first and foremost at the error handling. (And the error handling also including the handling of the error by the user.) Error handling is the decision making about what has to be done about the error.
That is one of the reasons why error reporting is an application level concern and strongly depends on the application workflow. In one application the "connection reset by peer" is a fatal error - in another it is a norm of life, error should be silently handled, connection should be reestablished and pending operation retried.
Thus the approach you mention - catch the exception, construct a new one with more detailed context information and re-throw it - is a valid one too: it is up to the top level application logic (or even user configuration) to decide whether the error is really an error or some special (re)action has to taken upon the condition.
What you have encountered is one of the weaknesses of so called out-of-line error handling (aka exceptions). And I'm not aware of any way to do it better. Exceptions create a secondary code path in the application and if error reporting is vital the design of the secondary code path has to treated just like the main code path.
Obvious alternative to the out-of-line error handling is the in-line error handling - good ol' return codes and log messages on the error conditions. That allows for a trick where application saves all low-severity log messages into internal (circular) buffer (of fixed or configurable size) and dumps them into the log only if high-severity error happens. This way more context information is available and different layers of application do not have to be actively aware of each other. That is also standard (and sometimes literally "standard" - mandated by law) way of error reporting in application fields like safety and mission critical software, were one is not allowed to miss errors.
I've never actually done this, but you could roll your own "stacktrace":
struct ErrorMessage {
const char *s;
ErrorMessage(const char *s) : msg(s) {}
~ErrorMessage() { if (s) std::cout << s << "\n"; }
void done() { s = 0; }
};
void someOperation() {
ErrorMessage msg("Doing the first bit");
// do various stuff that could throw
msg = "Doing the second bit";
// do more stuff that could throw
msg.done();
}
You can have several levels of this (although not necessarily use it at every level):
void handleFoo() {
ErrorMessage msg("Handling foo event");
someOperation();
msg.done();
}
And add more constructors and members:
void handleBar(const BarEvent &b) {
ErrorMessage msg(std::stringstream("Handling bar event ") << b.id);
someOperation();
msg.done();
}
And you needn't write the messages to std::cout. It could be to some logging object, and the object could queue them, and not actually output them to the log unless the catch site tells it to. That way, if you catch an exception that doesn't warrant logging, nothing is written.
It's not pretty, but it's prettier than try/catch/throw or checking return values. And if you forget to call done on success (for example if your function has multiple returns and you miss one), then you will at least see your mistake in the logs, unlike a resource leak.
[Edit: oh, and with a suitable macro you can store __FILE__ and __LINE__ in the ErrorMessage.]
You could add a call stack to your exception. I'm not sure how good this works for release builds but works like a charm with debug. You could do this in the constructor of your exception (to encapsulate it). See here for a starting point. This is possible as well on Linux - eventhough I dont remember how exactly.
I use RAII and exceptions and just have various unit-test-like assert statements throughout the code - if they fail, the the stack unwinds to where I can catch and handle them.
#define APP_ASSERT_MSG(Class,Assertion,szDescription) \
if ( !(Assertion) ) \
{ \
throw Class(__LINE__,__FILE__,szDescription); \
}
For most of my particular use case, all I care about is logging debug information, so my exception has the file and line number in it along with an error message (message is optional as I have an assert without it as well). You could easily add FUNCTION or an error code of some type for better handling.
I can then use it like this:
int nRet = download_file(...);
APP_ASSERT_MSG(DownloadException == ERR_OK, "Download failed");
This makes error handling and reporting much easier.
For really nasty debugging, I used GCC's function instrumentation to keep a trace list of what's going on. It works well, but slows down the app quite a bit.
What I do regularly, FWIW, is not use exceptions, but rather explicit error handling in a standard format (ie: using a macro). For example:
result = DoSomething();
CHECK_RESULT_AND_RETURN_ON_ERROR( result );
Now, obviously, this has many limitations design-wise:
Your return codes may need to be somewhat uniform
Code is cluttered with macros
You may need many macros for various check conditions
The upside, though, is as Dummy00001 said: you can effectively generate a stack trace on demand in the event of a serious error, by simply caching the results. I also use this paradigm to log all unexpected error conditions, so I can adjust the code later to handle unexpected conditions which occur "in the wild".
That's my 2c.
Here's how I handle error reporting in my libraries (this may or may not suit your situation).
First, as part of your design you want a "core" or "system" library that all this common logic will sit in. All you other libraries will then link to the core and use its error reporting APIs, so your whole system has a single compact chunk of logic for handling this mess.
Inside the core, provide a set of logging MACROS such as "LogWarning" and "LogFatal" with documented behavior and expected usage- for example, LogFatal should trigger a hard abort of the process but anything lower than "LogError" is simply advisory (does nothing). The macros can provide a "printf" interface that automatically appends the "LINE", "FILE", and "FUNC" macros as arguments to the underlying singleton object that handles your error reporting.
For the object itself I'll defer to you. However, you want public APIs that configure your "drains"- e.g. log to stderr, log to logfile, log to MS Services log, etc. You also want the underlying singleton to be thread safe, re-entrant where possible, and very robust.
With this system, you can make "exception reporting" ONE MORE DRAIN TYPE. Just add an internal API to that error manager object that packages your logged message as an exception, then throws it. Users can then enable AND DISABLE exceptions-on-error behavior in your code with ONE LINE in their apps. You can put try-catches around 3rd party or system code in you libraries that then calls a "Log..." macro in the catch clauses to enable clean re-throw behavior (with certain platforms and compiler options you can even catch things like segfaults using this).