Exercise: Search, “User Not Found” Exception

What’s Wrong?

In Exercise: Search a User By Lastname we chose to implement the UserDB::search_by_lastname() method to return an instance of User,

class UserDB
{
public:
    ...
    User search_by_lastname(const std::string& lastname) const;
    ...
};

This leads to unnatural coding in the not-found case: an empty/invalid user has to be returned:

User UserDB::search_by_lastname(const std::string& lastname) const
{
    for (size_t i=0; i<_users.size(); i++)
        if (_users[i].lastname() == lastname)
            return _users[i];    // ok, we have something that we can return

    return User();    // unnatural: what user is that?
}

Why is that unnatural?

  • I only want to give something that I own. If that was possible, I could return a const User& instead of a fat copy of something that I artificially create (and destroy soon thereafter).

  • If the caller wants to differentiate between “found” and “not found” (occasionally callers exhibit such desires), currently this has to be done by checking the validity of the returned object (using wrinkles such as User::isvalid()):

    User user = db.search_by_lastname("Faschingbauer");
    if (user.isvalid()) {
        // do something with it
    }
    else {
        // error handling, possibly
    }
    

Exercise

  • Create a new file, errors.h (which will hold all future exception classes).

  • In that file, implement (inline only) a custom exception, class UserNotFound (see here for how to create a custom exception).

  • Modify UserDB::search_by_lastname() to throw an instance of it in the not-found case.

  • Test this using the program below (feel free to use your own version of it):

#include "userdb.h"
#include <iostream>

int main()
{
    UserDB db;

    try {
        User user = db.search_by_lastname("Faschingbauer");

        // unreached because database is empty
        std::cout << "yay!" << user.lastname() << std::endl;
        return 0;
    }
    except (const UserNotFound& e) {
        std::cerr << "argh: no \"Faschingbauer\" in there" << std::endl;
        return 1;
    }
}

Dependencies

cluster_cxx03 C++ cluster_cxx03_data_encapsulation Data Encapsulation cluster_cxx03_exercises_userdb Exercises: User Database cluster_cxx03_functions_and_methods Functions and Methods cluster_cxx03_standard_library_miscellanea The Standard Library: Miscellaneous Topics cluster_cxx03_templates C++ Template Basics cluster_cxx03_exceptions Exceptions cluster_cxx03_stl Standard Template Library cluster_c The C Programming Language cluster_c_introduction Introduction cxx03_introduction Introduction c_introduction_installation Installation cxx03_introduction->c_introduction_installation cxx03_data_encapsulation_c Object Oriented Programming In Good Ol’ C cxx03_data_encapsulation_c->cxx03_introduction cxx03_data_encapsulation_ctor_custom Custom Constructor cxx03_data_encapsulation_classes_objects Classes and Objects cxx03_data_encapsulation_ctor_custom->cxx03_data_encapsulation_classes_objects cxx03_data_encapsulation_ctor_default Default Constructor cxx03_data_encapsulation_ctor_default->cxx03_data_encapsulation_ctor_custom cxx03_data_encapsulation_classes_objects->cxx03_introduction cxx03_data_encapsulation_classes_objects->cxx03_data_encapsulation_c cxx03_data_encapsulation_ctor_dtor More Constructors, Destructors cxx03_data_encapsulation_ctor_dtor->cxx03_data_encapsulation_ctor_custom cxx03_data_encapsulation_ctor_dtor->cxx03_data_encapsulation_ctor_default cxx03_exercises_userdb_userdb_vector_basic Exercise: Use std::vector in UserDB cxx03_exercises_userdb_user_default_ctor Exercise: Default Constructor (was: Arrays of Objects) cxx03_exercises_userdb_userdb_vector_basic->cxx03_exercises_userdb_user_default_ctor cxx03_stl_basics Standard Template Library: Basics cxx03_exercises_userdb_userdb_vector_basic->cxx03_stl_basics cxx03_exercises_userdb_userdb_search Exercise: Search a User By Lastname cxx03_exercises_userdb_userdb_insert Exercise: Insert a User into UserDB cxx03_exercises_userdb_userdb_search->cxx03_exercises_userdb_userdb_insert cxx03_exercises_userdb_user_default_ctor->cxx03_data_encapsulation_ctor_dtor cxx03_exercises_userdb_user_const Exercise: Use const cxx03_exercises_userdb_user_default_ctor->cxx03_exercises_userdb_user_const cxx03_exercises_userdb_user_access_methods Exercise: Access Methods for Members cxx03_exercises_userdb_user_simple_method Exercise: Simple Method (Users Age By n Years) cxx03_exercises_userdb_user_access_methods->cxx03_exercises_userdb_user_simple_method cxx03_functions_and_methods_methods Methods cxx03_exercises_userdb_user_access_methods->cxx03_functions_and_methods_methods cxx03_exercises_userdb_userdb_search_find_if Exercise: Search a User By Lastname (std::find_if) cxx03_exercises_userdb_userdb_search_find_if->cxx03_exercises_userdb_userdb_search cxx03_exercises_userdb_user_ctor Exercise: Transform struct User Into A Class cxx03_exercises_userdb_user_ctor->cxx03_data_encapsulation_ctor_custom cxx03_standard_library_miscellanea_string std::string cxx03_exercises_userdb_user_ctor->cxx03_standard_library_miscellanea_string cxx03_exercises_userdb_user_const->cxx03_exercises_userdb_user_access_methods cxx03_functions_and_methods_references References cxx03_exercises_userdb_user_const->cxx03_functions_and_methods_references cxx03_functions_and_methods_const const cxx03_exercises_userdb_user_const->cxx03_functions_and_methods_const cxx03_exercises_userdb_userdb_insert->cxx03_exercises_userdb_userdb_vector_basic cxx03_exercises_userdb_userdb_insert->cxx03_stl_basics cxx03_exercises_userdb_user_const_members Exercise: const Members cxx03_exercises_userdb_user_simple_method->cxx03_exercises_userdb_user_const_members cxx03_exercises_userdb_user_simple_method->cxx03_functions_and_methods_methods cxx03_exercises_userdb_userdb_search_notfound_exception Exercise: Search, “User Not Found” Exception cxx03_exercises_userdb_userdb_search_notfound_exception->cxx03_exercises_userdb_userdb_search_find_if cxx03_exceptions_try_catch try - catch cxx03_exercises_userdb_userdb_search_notfound_exception->cxx03_exceptions_try_catch cxx03_exercises_userdb_user_const_members->cxx03_data_encapsulation_ctor_dtor cxx03_exercises_userdb_user_const_members->cxx03_exercises_userdb_user_ctor cxx03_functions_and_methods_overloading Overloading cxx03_functions_and_methods_methods->cxx03_functions_and_methods_overloading cxx03_functions_and_methods_this this cxx03_functions_and_methods_references->cxx03_functions_and_methods_this cxx03_functions_and_methods_overloading->cxx03_data_encapsulation_classes_objects cxx03_functions_and_methods_this->cxx03_functions_and_methods_const cxx03_functions_and_methods_const->cxx03_functions_and_methods_methods cxx03_functions_and_methods_static static Methods cxx03_functions_and_methods_static->cxx03_functions_and_methods_references cxx03_functions_and_methods_operators Operator Overloading cxx03_functions_and_methods_operators->cxx03_functions_and_methods_static cxx03_templates_class_templates Class Templates cxx03_templates_function_templates Function Templates cxx03_templates_class_templates->cxx03_templates_function_templates cxx03_templates_function_templates->cxx03_exceptions_try_catch cxx03_exceptions_basics Basics cxx03_exceptions_try_catch->cxx03_exceptions_basics cxx03_exceptions_basics->cxx03_functions_and_methods_operators cxx03_stl_basics->cxx03_templates_class_templates