C++ exception catching - c++

After a successful catch , does the function that caught the exception exit ?
For example :
foo()
{
try
{
valid(name, name1, name2, name3, name3);
}
catch (int error)
{
std::cout << "Error number :" << error << std::endl;
}
std::cout << "Valid names" << std::endl;
}
If I catch an exception , will "Valid names" be printed ?

A caught exception will continue after the catch block provided you have not exited in the catch block once the commands in the catch block are finished.
The answer to your question is yes.

Related

Do you need to know what exception is going to occur to handle them in C++?

<C++>In exception handling, do you need to know what exception and where an exception is going to occur? Can you make a code which will print and notify us that an exception occurred somewhere in the program. I mean I have a program in which I don't know if an exception will occur or not, if one was to occur, then it will print to notify us.
Exception handling is something you should design for, and in fact it works very well together with RAII (https://en.cppreference.com/w/cpp/language/raii).
(Notr On embedded platforms using exceptions, is not so popular because of some runtime overhead). What I personally like about exceptions is that it separates error handling from the normal program flow (there will be hardly any if then else checks when done right)
// Exception handling should be part of your overal design.And many standard library functions can throw exceptions, It is always up to you where you handle them.
#include <iostream>
#include <string>
#include <stdexcept>
int get_int_with_local_exception_handling()
{
do
{
try
{
std::cout << "Input an integer (local exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
// stoi is a function that can throw exceptions
// look at the documentation https://en.cppreference.com/w/cpp/string/basic_string/stol
// and look for exceptions.
//
int value = std::stoi(input);
// if input was ok, no exception was thrown so we can return the value to the client.
return value;
}
// catch by const reference, it avoids copies of the exception
// and makes sure you cannot change the content
catch (const std::invalid_argument& e)
{
// std::exceptions always have a what function with readable info
std::cout << "handling std::invalid_argument, " << e.what() << "\n";
}
catch (const std::out_of_range& e)
{
std::cout << "handling std::out_of_range, " << e.what() << "\n";
}
} while (true);
}
int get_int_no_exception_handling()
{
std::cout << "Input an integer (without exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
int value = std::stoi(input);
return value;
}
int main()
{
try
{
// this function shows you can handle exceptions locally
// to keep program running
auto value1 = get_int_with_local_exception_handling();
std::cout << "your for input was : " << value1 << "\n";
// this function shows that exceptions can be thrown without
// catching, but then the end up on the next exception handler
// on the stack, which in this case is the one in main
auto value2 = get_int_no_exception_handling();
std::cout << "your input was : " << value1 << "\n";
return 0;
}
catch (const std::exception& e)
{
std::cout << "Unhandled exception caught, program terminating : " << e.what() << "\n";
return -1;
}
catch (...)
{
std::cout << "Unknown, and unhandled exception caught, program terminating\n";
}
}
Yes and no.
No, because any exception thrown via throw some_exception; can be catched via catch(...).
Yes, because catch(...) is not very useful. You only know that there was an excpetion but not more.
Typically exceptions carry information on the cause that you want to use in the catch. Only as a last resort or when you need to make abolutely sure not to miss any excpetion you should use catch(...):
try {
might_throw_unknown_exceptions();
} catch(std::exception& err) {
std::cout << "there was a runtime error: " << err.what();
} catch(...) {
std::cout << "an unknown excpetion was thrown.";
}
The C++ standard library uses inheritance only sparingly. Exceptions is only place where it is used extensively: All standard exceptions inherit from std::exception and it is good practice to inherit also custom exceptions from it.

Exception catching mechanism, C++

Consider this code:
int main()
{
try
{
throw std::range_error("");
}
catch (std::bad_alloc)
{
std::cout << "AAAA" << std::endl;
throw;
}
catch (std::range_error)
{
std::cout << "BBB" << std::endl;
throw;
}
catch (std::exception)
{
std::cout << "CCC" << std::endl;
}
std::cout << "DDD" << std::endl;
}
Here I throw an exception of type std::range_error and trying to catch it.
Logically the first catch block cannot catch it because of type mismatch(std::bad_alloc and std::range_error).
The second catch block must catch it because they are the same types of std::range_error.
And also, when I rethrow the exception in second catch block it must be caught in the third catch block.
So my output must be
BBB
CCC
DDD
But I only get the BBB output with the termination.
Can anybody please explain me the behavior??
When you re-throw an exception, you are throwing it completely out of the context of the current exception handling block.... So,
try
{
throw std::range_error("");
}
catch (std::bad_alloc)
{
std::cout << "AAAA" << std::endl;
throw;
}
catch (std::range_error)
{
std::cout << "BBB" << std::endl;
throw;
}
catch (std::exception)
{
std::cout << "CCC" << std::endl;
}
is one exception handling block. Therefore, on meeting the first throw in any of the catch blocks, it leaves the whole block to look for another handling block (try-catch) outside the current scope. if not found, the program terminates.
Please see try-catch block in C++
To print as you initially thought ... Live On Coliru ...
int main()
{
try{
try{
try{
throw std::range_error("");
}
catch (std::bad_alloc) {
std::cout << "AAAA" << std::endl;
throw;
}
}
catch (std::range_error) {
std::cout << "BBB" << std::endl;
throw;
}
}
catch (std::exception){
std::cout << "CCC" << std::endl;
}
std::cout << "DDD" << std::endl;
}
Prints:
BBB
CCC
DDD
For the record: please avoid using exceptions for control flow that could be done with simple if-else ladder in production code
To re-catch the range_error and new outer try catch block is required.
#include <iostream>
int main()
{
//outer try catch ------------------------
try {
// inner try catch ---------------------
try
{
throw std::range_error("");
}
catch (std::bad_alloc)
{
std::cout << "AAAA" << std::endl;
throw;
}
catch (std::range_error)
{
std::cout << "BBB" << std::endl;
throw;
}
// -------------------------------
}
catch (std::exception)
{
std::cout << "CCC" << std::endl;
}
// --------------------------------
std::cout << "DDD" << std::endl;
}
Output
BBB
CCC
DDD
This throw:
catch (std::range_error)
{
std::cout << "BBB" << std::endl;
throw; // <== this one
}
isn't itself within the body of a try, so when the exception handling mechanism will keep going out one scope at a time until it finds one. Since there is no other outer try, the exception isn't caught at all.
There is no reentrance in exception handling.

In a C++ command-line application, how should I catch exceptions at the top-level?

I am writing a command-line application in C++. If an unhandled exception occurs, I don't want the app to crash badly, but to clean up as well as possible and print an error message.
How should I catch exceptions at the top-level in order to avoid the program crashing? Should I catch std::exception, ... or something else?
The quality of the cleaning you can do is a function of the exception being thrown.
For example, an exception that you raise yourself (perhaps derived from std::exception; let's call it fooexception) could well be handled quite elegantly.
So really you want a catch site on these lines
try {
/*whatever*/
} catch (fooexception& fe){
/*ToDo - handle my exception*/
} catch (std::exception& e){
/*ToDo - handle this generically*/
} catch (...){
/*Hum. That's bad. Let's do my best*/
}
Extend this at your leisure. Just remember that in a sense, multiple catch blocks behave like if else blocks: always order with the specific exceptions first.
Well, you could catch both:
int main() {
try {
// do stuff
}
catch(const std::exception& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}
catch(...) {
std::cout << "Caught unknown exception." << std::endl;
}
}
You should catch both, and possibly more. If you use a more specific exception type somewhere in the call stack, try to catch that as well.
Consider the code:
try
{
process();
}
catch (const SpecificException& ex)
{
std::cerr << "SpecificException occured: " << ex.what() << std::endl;
}
catch (const std::runtime_error& ex)
{
std::cerr << "std::runtime_error occured: " << ex.what() << std::endl;
}
catch (...)
{
std::cerr << "Unknown error occured!" << std::endl; // should never happen hopefully
}
And remember to always sort by specificness of exceptions - the more specialized/derived first, as the runtime will stop at the first catch block able to process the exception (i.e. first catch block with exception type matching or being a base of).

How to add information about the topmost call/context to an exception

I would like to add information on what the program was about to do to my
exception handling. The old code had one big try-block around everything:
try {
read_cfg(); // a sub call might throw runtime_error
operation1();
operation2();
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
// FIXME: also show what we were trying to do
// FIXME: and what a user could try
<< "\n";
}
Example error message:
Error: file "foo.cfg" not found, while reading configuration.
Please make sure the file exists.
I converted the try-block into three blocks, but this feels odd:
try {
read_cfg(); // a sub call might throw runtime_error
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
<< "while reading configuration."
<< "\n";
}
try {
operation1();
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
<< "while performing operation 1."
<< "\n";
}
try {
operation2();
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
<< "while performing operation 2."
<< "\n";
}
I also tried to introduce one exception class per call (read_cfg_exception,
operation1_exception, operation2_exception). Since in read_cfg() the call to
open might throw, I catch its exception and convert it to a
read_cfg_exception, thereby saving the additional information, that something
whent wrong "while reading configuration". Yet this does not feel right either:
class read_cfg_exception;
void open(std::string name); // might throw std::runtime_error
void read_cfg()
{
try {
open("foo.cfg");
}
catch (std::runtime_error& e) {
throw read_cfg_exception(e.what() + "while reading configuration");
}
}
Therefor I have the question: What is a good pattern to show the additional
information of what the program was doing while the error occured.
take a look at POCO (c++ library) throwing system, that should answer all your questions, you'll learn a lot from that and many good style rules too. The answare to your question will be really long unfortunately (at least I don't know how to make it short).
Anyway don't implement something that makes your code not readable, in your example code is not readable and then not maintainable wich is not wanted.

Global exception handling in C++

Can i implement global exception handling in C++?
My requirement is try...catch block is not used in a piece of code then there should be a global exception handler which will handle all uncaught exception.
Can i achieve it, please give your valuable suggestion : )
I always wrap the outer-most function in a try-catch like this:
int main()
{
try {
// start your program/function
Program program; program.Run();
}
catch (std::exception& ex) {
std::cerr << ex.what() << std::endl;
}
catch (...) {
std::cerr << "Caught unknown exception." << std::endl;
}
}
This will catch everything. Good exception handling in C++ is not about writing try-catch all over, but to catch where you know how to handle it (like you seem to want to do). In this case the only thing to do is to write the error message to stderr so the user can act on it.
you can use a combination of set_terminate and current_exception()
i wanted to do the same, here's what i came up with
std::set_terminate([]() -> void {
std::cerr << "terminate called after throwing an instance of ";
try
{
std::rethrow_exception(std::current_exception());
}
catch (const std::exception &ex)
{
std::cerr << typeid(ex).name() << std::endl;
std::cerr << " what(): " << ex.what() << std::endl;
}
catch (...)
{
std::cerr << typeid(std::current_exception()).name() << std::endl;
std::cerr << " ...something, not an exception, dunno what." << std::endl;
}
std::cerr << "errno: " << errno << ": " << std::strerror(errno) << std::endl;
std::abort();
});
in addition to checking what(), it also checks ernno/std::strerror() - in the future i intend to add stack traces as well through exeinfo/backtrace() too
the catch(...) is in case someone threw something other than exception.. for example throw 1; (throw int :| )
In C++ the terminate function is called when an exception is uncaught. You can install your own terminate handler with the set_terminate function. The downside is that your terminate handler may never return; it must terminate your program with some operating system primitive. The default is just to call abort()
When an exception is raised, if is not caught at that point, it goes up the hierarchy until it is actually caught. If there is no code to handle the exception the program terminates.
You can run specific code before termination to do cleanup by using your own handlers of set_unexpected or set_terminate