Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have a file based hash table thing that can run into various filesystem or user errors. Initially I created all the data functions as bools like
bool add(int key, int value)
bool get(int key, int &value)
and so on where the input/output would go through the parameters and the success/fail would come as the function result.
Then I had some mmf wrapper classes I needed to fool-proof for the same project and I realized that they can fail at the constructor in which case returning a bool is not really an option so I added a bunch of
if (!somethingthatindicatesfail) throw std::exception("description here");
to them.
So now i have something that throws exceptions inside something that returns a bool and then there is system error codes that I also need to include in the error log.
Its a mess.. I'm going to rewrite all of the fail scenario logic but before I do, what is your preferred error handling/conveying method?
The end result I'm imagining is a module that doesn't crash but logs the errors, prevents further damage to the data and advises the user to shut it down.
As you already pointed out, you can't use return codes from constructors. So, if you want a single method that works for all the code, your only real choice is exception handling.
Note, however, that in some cases, it's preferable to just abort instead. In particular, exceptions will attempt to unwind the stack, but if the situation is dire enough, it's possible that could cause further damage, and aborting (existing without unwinding the stack) is a better option.
For that case, it can make sense to have (for example) a separate watch-dog that logs the problem and re-starts the program when/if it crashes. Being a separate process, it can continue and execute reasonably even if the program itself is bollixed up to the point that its only reasonable choice is to abort.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
For learning purposes I'm writing an interpreter of arithmetic equations in C++. When the user enters incorrect input, I'd want something like this to appear: (> is user input)
> 4+2*6+#-1
Lexer error: incorrect character '#' at position 7
What is the best way to approach that? Should I use exceptions, and if yes then should I create my own ones or just use something like std::runtime_error?
The trick is to maintain source location data all the way, through all the compilation passes. This way you can report
syntax errors, which are the most trivial, you have all the source location data handy at this stage, along with (depending on a parsing technique you're using) hints of what you'd rather expect at this point instead. A lot of such reporting can be inferred automatically with very little hinting.
semantic errors during compilation: for these you need to keep source locations for your IR nodes. E.g., for a binary arithmetic operation you'll have the location of the operator itself and sub-nodes will be able to show you locations of left and right side. There's no limit to how much information you can carry along here. For example, for any fully resolved identifier you may want to attach a location where it was declared, along with all the locations where it was referenced so far.
runtime errors: these are tricky, you don't have your rich IR at this stage, but you can emit debugging data in, for example, DWARF format, and unroll it back to your source locations when needed.
Runtime errors should be handled by your system debugger, so, no exceptions here. Semantic errors and syntax errors are, in most cases, recoverable, and you may want to display more than one, so, again, no reason to ever use exceptions.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
On the internet I have found advice such as:
"Don't throw an exception from inside a constructor!"
and
"If constructing the object, throw an exception from inside the constructor!!"
They contradict, can both be correct?
Take, for example, a class which opens a file, reads the data and closes the file, all within the constructor. It may encounter an error condition while opening or reading from the file. How should this error be handled?
What advice should I follow? Is throwing an exception from a constructor possible and is it good practice?
How should errors within constructors be handled if exceptions are not a good idea?
(I am using GCC C++14 on Linux)
Good advice:
Exceptions should not be allowed to escape from a destructor.
This may have morphed into bad advice:
Don't throw an exception from inside a constructor!
Exceptions are permitted within constructors. If construction fails, throwing an exception ensures that the object is not constructed, eliminating the possibility of using an object in an invalid state.
Another approach (to avoid) is to move the error prone tasks into an init() function and have the constructor do nothing that can fail. This may lead to use of objects in invalid states and may pollute all methods with checks to ensure init() has been called.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm building a c++ server library, where the user of the library will implement responses to the clients. If the program encounter any runtime error in the response implementation, the server should not exit, it should just close thread/connection.
I've found two ways to doing this.
Use threads and use __try __except in order to catch the exceptions, for example access violation - close the thread.
Start a new process for each connection. Response time to the clients will be longer if not reloading the processes, and will use more RAM.
I'm mainly interested in the first alternative, but it's not recommended in any forums or papers that I've read.
The point is to make the server stable and never terminating.
What option should I use?
the user of the library will implement responses to the clients. If the program encounter any runtime error in the response implementation
If you do not control 100% of the code being executed, going multi-process is the only way to make this stable.
Catching any "crash" SEH exceptions is a brittle business. The code may have bugs that don't cause any exceptions whatsoever, but just overwrite memory and you get some wrong behavior later on.
You could still catch these exceptions, but once you catch one, you should terminate the process, since you can't know what else has been messed up in the process' state. (And a better way might actually be to not catch them and just let the process terminate, giving you the chance to collect a crash dump.)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I need to implement default behavior of exit call. I don't know what should I do and what is the most suitable way to do this. I have read that it should close file descriptors and something else.
Should I close default streams (stdout,err and in) ?
How to exit from nested functions calls ? Using goto is bad practice, what is the best way to break out ?
Thanks.
Do all of the things listed in exit(3), then invoke the _exit(2) system call. Alternatively, use longjmp(3) to jump back up to the main() function, then return from it. This invokes the same behavior as calling exit(3), and is just as dependent on the C runtime, so if exit(3) is unavailable for some reason, returning from main() will probably not work correctly either.
Unfortunately, AFAIK there is no portable way to enumerate all of the functions which may have been registered with atexit(3) and on_exit(3), so you'll have to keep track of those manually (i.e. every time you call atexit(3) or on_exit(3), append the function pointer to a list). Flushing stdio(3) is 3 straightforward fflush(3) calls.
You do not need to close any streams or file descriptors; the OS should do that automatically (the OS must not leak streams and fd's, so it is responsible for cleaning them up).
NB: longjmp() is almost always wrong under C++; throw an exception instead. It generally should only be used under straight C.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am writing a generic class of template T.
It has a member function as
T findElement (T data1)
{
Tree<T> *tree=search (data1,TreeTop);
if (tree==NULL)
cout<<"\n Element Not FOund \n "';
else
// Usefult Part Of Code Which Returns A Data Of Type T (Generic)
}
Now if the 1st condition is true should I throw an exception?
Will it tamper with my functions return type.
A little explanation on how exception works will be helpful.
Whether or not to throw an exception is a subjective question which depends on your situation and coding style.
In general most folk would say only throw an exception in unusual circumstances - so if you expect many searches searches to return no result then perhaps returning a special or specially formed element is a good idea, if this is something that should rarely or never happens under normal circumstances then an exception would be judged as appropriate by most developers.
Regarding return type: when a function throws there is no return type as the function never returns, instead the program resumes on the first line of the catch in the calling context.
There are plenty of options. Which one should be chosen depends entirely on the context.
Return std::optional<T> (or boost::optional<T>) when not finding anything can be part of the normal program flow.
Throw an exception if not finding anything indicates an exceptional situation caused by the program's environment which is neither your code's fault nor the result of bad input (e.g. if another thread has emptied the container in just the wrong moment or if the element was not put there due to memory running out).
assert(false);, terminating the program. Do this when not finding anything can only mean that your own code is wrong, so quick termination is the best thing which can possibly happen.