Exception handling

Exceptions are unexpected events that occur during the execution of a program, disrupting the normal flow of execution.

Why Exception Handling?

Exception handling allows a program to respond to exceptional circumstances (like runtime errors) in a controlled and graceful manner, preventing abrupt termination.

Basic Exception Handling in C++

				
					try {
    // Block of code where exceptions might occur
} catch (ExceptionType e) {
    // Handler for specific exception type
} catch (...) {
    // Default handler for any other exceptions
}

				
			
				
					#include <iostream>

int main() {
    try {
        int a = 10, b = 0;
        if (b == 0)
            throw "Division by zero";
        std::cout << "Result: " << a / b << std::endl;
    } catch (const char* msg) {
        std::cerr << "Error: " << msg << std::endl;
    }
    return 0;
}

				
			
				
					// output //
Error: Division by zero

				
			

Explanation:

  • The try block encloses the code that might throw an exception.
  • Inside the try block, we have two integers a and b, with b initialized to 0.
  • Following C++ conventions, we check if b is equal to 0. If it is, we throw a string literal "Division by zero".
  • The catch block catches the exception of type const char*, which is the type of the thrown string literal.
  • Inside the catch block, we print the error message to the standard error stream using std::cerr.

The output is generated because the exception "Division by zero" is thrown when b equals 0, and it’s caught by the catch block, printing the error message to the standard error stream.

Standard Exception Classes in C++

Standard exception classes are predefined exception types provided by the C++ Standard Library. They are designed to cover common types of errors that can occur during program execution. These classes are part of the <stdexcept> header and are organized in a hierarchical structure.

Standard Exception Hierarchy

std::exception

  • Base class for all standard C++ exceptions.
  • Provides a virtual member function what() to retrieve a description of the exception.

std::logic_error

  • Indicates errors in the program’s logic or internal errors that can be detected at compile time.
  • Common subclasses include:

std::invalid_argument: Thrown when a function argument is invalid.

std::domain_error: Thrown when a mathematical function is called with a domain error, such as sqrt(-1).

std::length_error: Thrown when an attempt is made to exceed the maximum length of a container.

std::out_of_range: Thrown when an index is out of the allowed range.

std::runtime_error

  • Indicates errors detected during runtime that are not related to the program’s logic.
  • Common subclasses include:

std::range_error: Thrown when a mathematical operation results in a value outside the range representable by the type.

std::overflow_error: Thrown when an arithmetic overflow occurs during a computation.

std::underflow_error: Thrown when an arithmetic underflow occurs during a computation.

std::system_error: Thrown when a system call fails.

				
					#include <iostream>
#include <stdexcept>

int main() {
    try {
        throw std::runtime_error("Something went wrong!");
    } catch (const std::runtime_error& e) {
        std::cerr << "Caught a runtime error: " << e.what() << std::endl;
    }
    return 0;
}

				
			
				
					// output //
Caught a runtime error: Something went wrong!

				
			

Explanation:

  • In this example, we’re using std::runtime_error, a subclass of std::exception, to represent a runtime error.
  • We throw an instance of std::runtime_error with the message "Something went wrong!" inside the try block.
  • The catch block catches the exception by reference, allowing us to access information about the exception through the e variable.
  • We print the error message returned by e.what() to the standard error stream.

Benefits of Using Standard Exception Classes

  1. Clarity: Standard exception classes provide meaningful names for common types of errors, making code more readable and understandable.
  2. Consistency: By using standard exception classes, you adhere to a common convention, improving the consistency of error handling across different codebases.
  3. Robustness: Standard exception classes are designed and tested to handle various exceptional situations reliably, reducing the likelihood of bugs and errors in error-handling code.

Advanced Exception Handling Techniques in C++

Rethrowing Exceptions

Rethrowing allows an exception caught in one part of the program to be thrown again in another part. This is useful when you want to handle an exception at a higher level of the call stack while preserving information about the original exception.

				
					#include <iostream>
#include <stdexcept>

void foo() {
    try {
        throw std::runtime_error("Error in foo()");
    } catch (const std::runtime_error& e) {
        std::cerr << "Caught in foo(): " << e.what() << std::endl;
        throw; // Rethrow the exception
    }
}

int main() {
    try {
        foo();
    } catch (const std::runtime_error& e) {
        std::cerr << "Caught in main(): " << e.what() << std::endl;
    }
    return 0;
}

				
			
				
					// output //
Caught in foo(): Error in foo()
Caught in main(): Error in foo()

				
			

Explanation:

  • In the foo() function, we throw an instance of std::runtime_error with the message "Error in foo()".
  • We catch the exception inside foo() and print a message indicating that it was caught in foo().
  • After handling the exception, we use the throw; statement to rethrow the exception.
  • In the main() function, we call foo() inside a try block and catch any std::runtime_error exceptions that may occur.
  • When the exception is rethrown from foo(), it’s caught in the catch block in main(), and we print a message indicating that it was caught in main().

Benefits of Advanced Exception Handling Techniques

  1. Error Propagation: Rethrowing exceptions allows errors to propagate up the call stack, enabling centralized error handling at higher levels of the program.
  2. Preserving Context: By rethrowing exceptions, you retain information about the original exception, such as the type and message, which can aid in debugging and error diagnosis.
  3. Separation of Concerns: Advanced exception handling techniques help separate error-handling logic from regular program logic, leading to cleaner and more maintainable code.

Custom Exception Classes in C++

Overview

While the C++ Standard Library provides a variety of standard exception classes, you may encounter situations where none of these classes precisely fit the error condition you need to represent. In such cases, you can define your own custom exception classes to encapsulate specific error types.

Steps to Define Custom Exception Classes

  1. Inheritance: Typically, custom exception classes inherit from std::exception or one of its subclasses, such as std::runtime_error or std::logic_error.
  2. Override: Override the what() method from the base class to provide a custom error message.
  3. Construction: Optionally, define constructors to initialize the exception object with relevant information.
				
					#include <iostream>
#include <stdexcept>

class MyException : public std::exception {
public:
    MyException(const std::string& message) : msg(message) {}
    const char* what() const noexcept override {
        return msg.c_str();
    }
private:
    std::string msg;
};

int main() {
    try {
        throw MyException("Custom exception occurred!");
    } catch (const MyException& e) {
        std::cerr << "Caught a custom exception: " << e.what() << std::endl;
    }
    return 0;
}

				
			
				
					// output //
Caught a custom exception: Custom exception occurred!

				
			

Explanation:

  • We define a custom exception class MyException that inherits from std::exception.
  • The MyException class contains a member variable msg to store the error message.
  • We define a constructor for MyException that initializes msg with the provided message.
  • We override the what() method to return the msg as a C-style string.
  • In the main() function, we throw an instance of MyException with the message "Custom exception occurred!".
  • We catch the exception by reference, allowing us to access the error message through the e variable, and print it to the standard error stream.

Benefits of Custom Exception Classes

  1. Specificity: Custom exception classes allow you to precisely define and communicate the nature of an error, leading to clearer error messages and more targeted error handling.
  2. Domain-specific Errors: In applications with domain-specific logic, custom exception classes can be tailored to represent unique error conditions specific to that domain.
  3. Encapsulation: By encapsulating error details within custom exception classes, you promote encapsulation and maintain a separation of concerns between error handling and regular program logic.

Summary

std::exceptionBase class for all standard C++ exceptions. Provides a what() method to retrieve a description of the exception.
std::logic_errorIndicates errors in the program’s logic or internal errors detected at compile time. Common subclasses include:
std::invalid_argument
std::domain_error
std::length_error
std::out_of_range
std::runtime_errorIndicates errors detected during runtime that are not related to the program’s logic. Common subclasses include: 
std::range_error
std::overflow_error
std::underflow_error
std::system_error
std::invalid_argumentThrown when a function argument is invalid.
std::domain_errorThrown when a mathematical function is called with a domain error, such as sqrt(-1).
std::length_errorThrown when an attempt is made to exceed the maximum length of a container.
std::out_of_rangeThrown when an index is out of the allowed range.
std::range_errorThrown when a mathematical operation results in a value outside the range representable by the type.
std::overflow_errorThrown when an arithmetic overflow occurs during a computation.
std::underflow_errorThrown when an arithmetic underflow occurs during a computation.
std::system_errorThrown when a system call fails.

Exception handling in C++ provides a robust mechanism to deal with unexpected situations in programs. By using try, catch, and throw, you can handle errors gracefully, improving the reliability and maintainability of your code.Happy coding !❤️

Table of Contents

Contact here

Copyright © 2025 Diginode

Made with ❤️ in India