C++ Custom Exceptions
In this page:
Why Custom Exceptions?
The exceptions built into the standard library are useful but generic; defining your own exception types lets you create error categories that map precisely onto your application's own business logic, which makes debugging and targeted error handling far cleaner.
Example: Why Custom Exceptions?
#include <iostream>
#include <string>
class InvalidAgeError {
public:
std::string message = "Age cannot be negative";
};
int main() {
try {
throw InvalidAgeError();
} catch (InvalidAgeError &e) {
std::cout << e.message << std::endl;
}
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Creating a Basic Exception Class
At its simplest, a custom exception class is just an ordinary class with whatever data and methods you decide it needs — you throw instances of it and catch them by that specific class type, just like any standard exception.
Example: Creating a Basic Exception Class
#include <iostream>
#include <string>
class MyException {
public:
std::string message;
MyException(std::string msg) : message(msg) {}
};
int main() {
try {
throw MyException("Something broke");
} catch (MyException &e) {
std::cout << e.message << std::endl;
}
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Inheriting from std::exception
The professional way to build a custom exception is to inherit from std::exception and override its virtual what() method. Doing so lets generic catch blocks written for std::exception handle your custom exceptions too, without needing to know about your specific type.
Example: Inheriting from std::exception
#include <iostream>
#include <exception>
class MyException : public std::exception {
public:
const char *what() const noexcept override {
return "Custom exception occurred";
}
};
int main() {
try {
throw MyException();
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
}
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Custom Exceptions with Custom Data
Because your exception is a real class, it can carry custom member data along with the failure — an error code, a file path, a timestamp — giving the code that catches it far richer information than a bare error message alone.
Example: Custom Exceptions with Custom Data
#include <iostream>
#include <exception>
class ValidationError : public std::exception {
public:
int errorCode;
ValidationError(int code) : errorCode(code) {}
const char *what() const noexcept override {
return "Validation failed";
}
};
int main() {
try {
throw ValidationError(422);
} catch (ValidationError &e) {
std::cout << e.what() << " code=" << e.errorCode << std::endl;
}
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Practical Usage in Validation
In practice, custom exceptions are typically thrown from inside validation logic or system-level operations, where they communicate exactly what went wrong to whatever code further up the stack is responsible for deciding how to respond.
Example: Practical Usage in Validation
#include <iostream>
#include <exception>
class InvalidAgeError : public std::exception {
public:
const char *what() const noexcept override {
return "Age must be non-negative";
}
};
void checkAge(int age) {
if (age < 0) throw InvalidAgeError();
}
int main() {
try {
checkAge(-5);
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
}
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 5 topics to unlock
0/5 topics done
Complete these topics first: