Lei Mao bio photo

Lei Mao

Machine Learning, Artificial Intelligence, Computer Science.

Twitter Facebook LinkedIn GitHub   G. Scholar E-Mail RSS

Introduction

Sometimes we would like to keep running our program without termination even if some errors and exceptions occur. This is particularly required for applications running on the cloud. Therefore, appropriate exception handlings are very important.


In this blog post, I am going to show how to use try and catch block to catch the exceptions.

Example

The standard C++ exception classes, such as std::runtime_error, are usually inherited from std::exception, we can also customize our own exception class as well.

#include <iostream>
#include <stdexcept>
#include <exception>
#include <limits>

double division(double x, double y)
{
    if (y == 0)
    {
        throw std::runtime_error{"Divisor cannot be zero!"};
    }
    return x / y;
}

// Customize exception
class bad_input_error : public std::exception 
{
public:
    // https://en.cppreference.com/w/cpp/error/exception/what
    const char* what() const throw()
    {
        return "Got bad input!";
    }
};

void readValues(double& x, double& y)
{
    std::cout << "Please input dividend: " <<std::endl;
    std::cin >> x;
    if (!std::cin)
    {
        // Reset std::cin
        // Otherwise std::cin would be abnormal forever
        // https://gist.github.com/jpkrause/4a1aa400d45197ca3253
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        throw bad_input_error{};
    }
    std::cout << "Please input divisor: " <<std::endl;
    std::cin >> y;
    if (!std::cin)
    {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        throw bad_input_error{};
    }
}

int main()
{
    double x;
    double y;
    double z;

    while (true)
    {
        try
        {
            readValues(x, y);
        }
        catch (bad_input_error& error)
        {
            std::cerr << "Runtime error: " << error.what() << std::endl;
            std::cerr << "Please input values again." << std::endl;
            continue;
        }
        try
        {
            z = division(x, y);
            std::cout << "Quotient: " << std::endl;
            std::cout << z << std::endl;
        }
        catch (std::runtime_error& error)
        {
            std::cerr << "Runtime error: " << error.what() << std::endl;
            continue;
        }
        // Of course, multiple different catch blocks could follow the try block.
    }
    return 0;
}

To compile the program, run the following command in the terminal.

$ g++ exception.cpp -o exception

We run the program to compute the quotients given the input values.

$ ./exception 
Please input dividend: 
10
Please input divisor: 
2
Quotient: 
5
Please input dividend: 
10
Please input divisor: 
0
Runtime error: Divisor cannot be zero!
Please input dividend: 
michael
Runtime error: Got bad input!
Please input values again.
Please input dividend: 
10
Please input divisor: 
2
Quotient: 
5
Please input dividend: 

Conclusions

Exception handling is very important for programs in production.