In: Computer Science
Exceptions in C++
Tasks
//csc232.h
#ifndef CSC232_LAB07_H #define CSC232_LAB07_H #define FALSE 0 #define TRUE 1 #define EXECUTE_BLOCK TRUE // TODO: When you create your pull request, make sure all of the following are set to TRUE #define TEST_INVALID_TARGET_EXCEPTION FALSE #define TEST_UNEXPECTED_ERROR_EXCEPTION FALSE #define TEST_INVALID_RANGE_EXCEPTION FALSE #include <stdexcept> #include <string> /** * @brief Custom exception to be thrown whenever a logical error is encountered. */ class TargetNotFoundException : public std::logic_error { public: /** * @brief Initializing constructor. * @param message an informative message to include with this logic_error */ explicit TargetNotFoundException(const std::string &message = "") : std::logic_error("Target not found: " + message) { // Intentionally empty as initialization utilizes an initializer list } }; // TODO: Create a custom exception class named InvalidTargetException that extends std::invalid_argument // TODO: Create a custom exception class named UnexpectedErrorException that extends std::runtime_error // TODO: Create a custom exception class named InvalidRangeException that extends std::range_error /** * @brief A demonstration of throwing the TargetNotFoundException. * @param target the target that wasn't found during processing */ void ThrowTargetNotFoundException(const std::string& target) { throw TargetNotFoundException(target); } /** * @brief A demonstration of throwing the InvalidTargetException. * @param error the error encountered during processing */ void ThrowInvalidTargetException(const std::string& error) { // TODO: throw an InvalidTargetException with the given error message // TODO: when done, change TEST_INVALID_TARGET_EXCEPTION to TRUE and commit your changes } /** * @brief A demonstration of throwing the UnexpectedErrorException. * @param error the error encountered during processing */ void ThrowUnexpectedErrorException(const std::string& error) { // TODO: throw an UnexpectedErrorException with the given error message // TODO: when done, change TEST_UNEXPECTED_ERROR_EXCEPTION to TRUE and commit your changes } /** * @brief A demonstration of throwing the InvalidRangeException. * @param error the error encountered during processing */ void ThrowInvalidRangeException(const std::string& error) { // TODO: throw an InvalidRangeException with the given error message // TODO: when done, change TEST_INVALID_RANGE_EXCEPTION to TRUE and commit your changes } #endif //CSC232_LAB07_H
//main.cpp
#include <cstdlib> #include <iostream> #include <string> #include "csc232.h" /** * @brief A contrived function that always throws an exception * @param target presumably something this function seeks to find * @return true * @throws ThrowTargetNotFoundException always! */ bool findSomeTarget(const std::string& target) { ThrowTargetNotFoundException(target); return true; } /** * @brief A simple demonstration on how to handle exceptions and gracefully exit. * @return EXIT_SUCCESS upon successfully handling exceptional code. */ int main() { std::cout << "A program doomed to failure..." << std::endl << std::endl; bool targetDoesNotExist{false}; std::string target; // TODO: Run this main target with EXECUTE_BLOCK initially set to true and observe the exit code #if EXECUTE_BLOCK std::cout << "Enter a target value to search: "; std::cin >> target; targetDoesNotExist = findSomeTarget(target); #else // TODO: Toggle EXECUTE_BLOCK to false, run this target again and observe the exit code try { std::cout << "Enter a target value to search: "; std::cin >> target; targetDoesNotExist = findSomeTarget(target); } catch (const TargetNotFoundException& notFoundException) { std::cerr << notFoundException.what() << std::endl; targetDoesNotExist = true; } if (targetDoesNotExist) { std::cout << "I told you so... this program was doomed to fail!" << std::endl; std::cout << "But at least it did so gracefully ;-)" << std::endl << std::endl; } #endif return EXIT_SUCCESS;
The rest of exceptions were added (required as part of TODOs) in similar fashion.
Also using the MACROS defined in header file, I added new code segments in the main class to call exception specific class in header file to test each scenarios. 1) With only throwing exception. 2) Handling exception by using try catch.
The files are provided below in code blocks.
#ifndef CSC232_LAB07_H
#define CSC232_LAB07_H
#define FALSE 0
#define TRUE 1
#define EXECUTE_BLOCK FALSE
// TODO: When you create your pull request, make sure all of the following are set to TRUE
#define TEST_INVALID_TARGET_EXCEPTION FALSE
#define TEST_UNEXPECTED_ERROR_EXCEPTION FALSE
#define TEST_INVALID_RANGE_EXCEPTION FALSE
#include <stdexcept>
#include <string>
/**
* @brief Custom exception to be thrown whenever a logical error is encountered.
*/
class TargetNotFoundException : public std::logic_error {
public:
/**
* @brief Initializing constructor.
* @param message an informative message to include with this logic_error
*/
explicit TargetNotFoundException(const std::string &message = "")
: std::logic_error("Target not found: " + message) {
// Intentionally empty as initialization utilizes an initializer list
}
};
// TODO: Create a custom exception class named InvalidTargetException that extends std::invalid_argument
/**
* @brief Custom exception to be thrown whenever invalid target is encountered
*/
class InvalidTargetException : public std::logic_error {
public:
explicit InvalidTargetException(const std::string &message = "")
: std::logic_error("Invalid target: " + message) {
}
};
// TODO: Create a custom exception class named UnexpectedErrorException that extends std::runtime_error
/**
* @brief Custom exception to be thrown whenever unexpected exception is encountered
*/
class UnexpectedErrorException : public std::logic_error {
public:
explicit UnexpectedErrorException(const std::string &message = "")
: std::logic_error("Unexpected error: " + message) {
}
};
// TODO: Create a custom exception class named InvalidRangeException that extends std::range_error
/**
* @brief Custom exception to be thrown whenever unexpected range is encountered
*/
class InvalidRangeException : public std::logic_error {
public:
explicit InvalidRangeException(const std::string &message = "")
: std::logic_error("Invalid range: " + message) {
}
};
/**
* @brief A demonstration of throwing the TargetNotFoundException.
* @param target the target that wasn't found during processing
*/
void ThrowTargetNotFoundException(const std::string& target) {
throw TargetNotFoundException(target);
}
/**
* @brief A demonstration of throwing the InvalidTargetException.
* @param error the error encountered during processing
*/
void ThrowInvalidTargetException(const std::string& error) {
// TODO: throw an InvalidTargetException with the given error message
throw InvalidTargetException(error);
// TODO: when done, change TEST_INVALID_TARGET_EXCEPTION to TRUE and commit your changes
}
/**
* @brief A demonstration of throwing the UnexpectedErrorException.
* @param error the error encountered during processing
*/
void ThrowUnexpectedErrorException(const std::string& error) {
// TODO: throw an UnexpectedErrorException with the given error message
throw UnexpectedErrorException(error);
// TODO: when done, change TEST_UNEXPECTED_ERROR_EXCEPTION to TRUE and commit your changes
}
/**
* @brief A demonstration of throwing the InvalidRangeException.
* @param error the error encountered during processing
*/
void ThrowInvalidRangeException(const std::string& error) {
// TODO: throw an InvalidRangeException with the given error message
throw InvalidRangeException(error);
// TODO: when done, change TEST_INVALID_RANGE_EXCEPTION to TRUE and commit your changes
}
#endif //CSC232_LAB07_H
#include <cstdlib>
#include <iostream>
#include <string>
#include "csc232.h"
/**
* @brief A contrived function that always throws an exception
* @param target presumably something this function seeks to find
* @return true
* @throws ThrowTargetNotFoundException always!
*/
bool findSomeTarget(const std::string& target) {
ThrowTargetNotFoundException(target);
return true;
}
/**
* @brief A simple demonstration on how to handle exceptions and gracefully exit.
* @return EXIT_SUCCESS upon successfully handling exceptional code.
*/
int main() {
std::cout << "A program doomed to failure..." << std::endl << std::endl;
bool targetDoesNotExist{false};
std::string target;
// TODO: Run this main target with EXECUTE_BLOCK initially set to true and observe the exit code
#if EXECUTE_BLOCK
std::cout << "Enter a target value to search: ";
std::cin >> target;
targetDoesNotExist = findSomeTarget(target);
#else
// TODO: Toggle EXECUTE_BLOCK to false, run this target again and observe the exit code
try {
std::cout << "Enter a target value to search: ";
std::cin >> target;
targetDoesNotExist = findSomeTarget(target);
} catch (const TargetNotFoundException ¬FoundException) {
std::cerr << notFoundException.what() << std::endl;
targetDoesNotExist = true;
}
if (targetDoesNotExist) {
std::cout << "I told you so... this program was doomed to fail!" << std::endl;
std::cout << "But at least it did so gracefully ;-)" << std::endl << std::endl;
}
#endif
// test invalid target exception
#if TEST_INVALID_TARGET_EXCEPTION
ThrowInvalidTargetException("the target is invalid");
#else
try {
ThrowInvalidTargetException("the target is invalid");
} catch(const InvalidTargetException& exception ) {
std::cerr << exception.what() << std::endl;
std::cout<< "Handled Invalid target exception gracefully" <<std::endl;
}
#endif
// test unexpected exception.
#if TEST_UNEXPECTED_ERROR_EXCEPTION
ThrowUnexpectedErrorException("Unexpected exception");
#else
try {
ThrowUnexpectedErrorException("Unexpected exception");
} catch(const UnexpectedErrorException& exception) {
std::cerr << exception.what() << std::endl;
std::cout<< "Handled Unexpected exception gracefully" <<std::endl;
}
#endif
// test invalid range
#if TEST_INVALID_RANGE_EXCEPTION
ThrowInvalidRangeException("Invalid range");
#else
try {
ThrowInvalidRangeException("Invalid range");
} catch(const InvalidRangeException& exception) {
std::cerr << exception.what() << std::endl;
std::cout<< "Handled Invalid exception gracefully" <<std::endl;
}
#endif
return EXIT_SUCCESS;
}
The screenshot of the code working with all the macros marked as FALSE is present below. In this case the all the exception thrown by methods are handled gracefully.
Screenshot of the code to understand the indentation is present below.