๐ŸŽ“ A1Learner
๐Ÿ”
0 of 34 lessons completed

C++ Exceptions in Depth

A standard exception is an error object that carries a message about a failure. The what() method returns that message for a catch block to print.

A message in a runtime error

The try block throws a std::runtime_error with a message. The catch block prints the message through what().

#include <iostream>
#include <stdexcept>

int main() {
  try {
    throw std::runtime_error("File is missing");
  } catch (const std::runtime_error& error) {
    std::cout << error.what() << "\n";
  }
  return 0;
}

Catching through the base type

std::stoi cannot read the text abc as a number, so it throws. The catch names const std::exception& and prints the message through what().

#include <iostream>
#include <exception>
#include <string>

int main() {
  try {
    int value = std::stoi("abc");
    std::cout << value << "\n";
  } catch (const std::exception& error) {
    std::cout << error.what() << "\n";
  }
  return 0;
}

A custom error class

EmptyBoxError inherits from std::exception and overrides what(). The catch prints the message of the custom class.

#include <iostream>
#include <exception>

class EmptyBoxError : public std::exception {
public:
  const char* what() const noexcept override {
    return "The box is empty";
  }
};

int main() {
  try {
    throw EmptyBoxError();
  } catch (const std::exception& error) {
    std::cout << error.what() << "\n";
  }
  return 0;
}

A custom error with no catch

This program throws EmptyBoxError with no try block around the throw. The program stops, and the two lines below report the error.

#include <iostream>
#include <exception>

class EmptyBoxError : public std::exception {
public:
  const char* what() const noexcept override {
    return "The box is empty";
  }
};

int main() {
  throw EmptyBoxError();
  return 0;
}

Example

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

class EmptyBoxError : public std::exception {
public:
  const char* what() const noexcept override {
    return "The box is empty";
  }
};

void load(int step) {
  if (step == 1) {
    throw std::runtime_error("File is missing");
  }
  if (step == 2) {
    throw EmptyBoxError();
  }
}

int main() {
  try {
    load(1);
  } catch (const std::exception& error) {
    std::cout << "First: " << error.what() << "\n";
  }
  try {
    load(2);
  } catch (const std::exception& error) {
    std::cout << "Second: " << error.what() << "\n";
  }
  return 0;
}

Key points

  • The <stdexcept> header gives a program std::runtime_error.
  • std::runtime_error holds a message given when the error is made.
  • The what() method returns the message held by an exception.
  • A catch for const std::exception& catches errors derived from std::exception.
  • std::stoi throws an exception when its text cannot be read as a number.
  • A custom error class can inherit from std::exception and override what().
  • An exception with no catch stops the program through terminate.

In this example, the load function throws a std::runtime_error for step 1 and an EmptyBoxError for step 2. Each call sits in its own try block. The two catch blocks print the two messages in order.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does the what() method return?