Sunday, December 22, 2024

Standard Library Exception Categories

Overview
This discusses various standard library exceptions with examples.

Details
The following discusses details about different exception with examples.

logic_error
These are derived from logic_error class defined in std library. 
NameDescription
domain_errorThis error is reported by functions that internally call mathematical functions implemented in std library. This exception is thrown when  mathematical functions return inf or NaN.  Note that none of standard library functions throw this error.

Example
 //ret:inf
 auto ret = pow(0,-1);
future_errorThis reports future object related errors with error_code.

Example
    /*prints
    Exception caught (future_error):
    Value: 1 (future_errc::future_already_retrieved)
    Category: future
    Message: Future already retrieved
    */
    promise<int> prom;

    try 
    {
        prom.get_future();
        // throws future_error with future_already_retrieved
prom.get_future(); } catch (future_error& e) { error_condition cond = e.code().default_error_condition(); cerr << "Exception caught (future_error):" << endl;
        cerr << "Value: " << cond.value() << endl;
        cerr << "Category: " << cond.category().name() << endl;
cerr << "Message: " << cond.message() << endl;
}
invalid_argument                This reports invalid argument related errors.
.
Example
    /*prints
        bitset::_M_copy_from_ptr
    */

    try 
    {
        //throws error because cannot convert the input string to a number.
        bitset<128>("ffff").to_ulong();
    }
    catch (invalid_argument& e) 
    {
        cerr << e.what() << endl;
    }
length_errorThis reports length related errors. e.g., if it's too large.

Example
    /*prints
        cannot create std::vector larger than max_size()
    */

    try 
    {
        //throws error because cannot allocate vector of 18446744073709551615 ints.
        vector<int>(-1);
    }
    catch (length_error& e) 
    {
        cerr << e.what() << endl;
    }
out_of_rangeThis reports errors such as  an argument that is out of its valid range.

Example
    /*prints
        basic_string::append: __pos (which is 1) > this->size() (which is 0)
    */

    try 
    {
        //throws error because index 1 is past the length of string "".
        string().append("", 1, 0);
    }
    catch (out_of_range& e) 
    {
        cerr << e.what() << endl;
    }

misc_error
Note that there is no misc_error class defined in std library. It's given only for notation.
NameDescription
bad_array_new_length                          This error is reported when the invalid array size is supplied.

Example
    /*prints
       std::bad_array_new_length
    */

    try 
    {
        //throws error because negative length input is supplied.
        auto n = -1;
        new int[n] ;
    }
    catch (bad_array_new_length & e) 
    {
        cerr <<  e.what() << endl;
    }
bad_allocThis error is reported when required storage could not be allocated by the new functions.

Example
    /*prints
      std::bad_alloc
    */

    try 
    {
        //throws error because it cannot allocate array of 4294967295 ints.
        new int[numeric_limits<uint>::max()];
    }
    catch (bad_alloc & e) 
    {
        cerr <<  e.what() << endl;
    }
bad_castThis error is reported by dynamic_cast when it fails the run-time check performed on references to polymorphic class types.

Example
    /*prints
      std::bad_cast
    */

    try 
    {
        //throws error because exception  class is not derived from bad_cast class. 
        //It's other way round.
         dynamic_cast<bad_cast&>( exception());
    }
    catch (bad_cast & e) 
    {
        cerr <<  e.what() << endl;
    }

bad_typeid                              This error is reported btypeid when applied on a pointer to a polymorphic type which has a null pointer value.

Example
    /*prints
     std::bad_typeid
    */

    try 
    {
        //throws error because nullptr is passed as input.
         typeid(* ( (exception*)nullptr)  ).name();
    }
    catch (bad_typeid   & e) 
    {
        cerr <<  e.what() << endl;
    }

bad_exceptionis reported by unexpected_handler, if the bad_exception is declared in throw specification of the function declaration, when such a function throws wrong type. 

Example
    /*prints
     unexpected handler called
     caught bad_exception:std::bad_exception
    */
void myunexpected () 
{
    cerr << "unexpected handler called" << endl;
    throw;
}

void myfunction () throw (int,bad_exception) 
{
    // throws char (not in exception-specification)
    throw 'x'; 
}
    set_unexpected (myunexpected);
    try 
    {
        myfunction();
    }
    catch (int) { cerr << "caught int" << endl; }
    catch (bad_exception e) { cerr << "caught bad_exception:" << e.what() << endl; }
    catch (...) { cerr << "caught some other exception" << endl; }

runtime_error
underlying os or file system related exceptions such as system_error such as file does not exist. These are derived from runtime_error class defined in std library.
NameDescription
range_errorThis error is reported  when the result of a computation cannot be represented by the destination type.

Example
    /*prints
     wstring_convert::from_bytes
    */

    try 
    {
        //throws error because char range passed as input should be within 0x00 - 0x80.
         wstring_convert<codecvt_utf8<char32_t>,char32_t>().from_bytes(string("\xff"));
    }
    catch (range_error& e) 
    {
        cerr <<  e.what() << endl;
    }
overflow_errorThis is reported for arithmetic overflow errors.

Example
    /*prints
     w_Base_bitset::_M_do_to_ulong
    */

    try 
    {
        bitset<128> b;
        b[64] = 1;
        //throws error because number is too large 
        b.to_ulong();
    }
    catch (overflow_error& e) 
    {
        cerr <<  e.what() << endl;
    }
underflow_errorThis is reported  for arithmetic underflow errors. Standard library functions don't throw this error.
system_error                              This is reported for  underlying os related exceptions with error_code
e.g., thread().detach() throws this exception with errc::invalid_argument since  thread object does not have a handler.

Example
    /*prints
    Exception caught (system_error):
    Value: 22 (errc::invalid_argument)
    Category: generic
    Message: Invalid argument
    */
  

    try 
    {
        //throws error because thread is invalid
        thread().detach();  
    }
    catch (system_error& e) 
    {
        error_condition cond = e.code().default_error_condition();
        cerr << "Exception caught (system_error):" << endl;
        cerr << "Value: " << cond.value() << endl;
        cerr << "Category: " << cond.category().name() << endl;
        cerr << "Message: " << cond.message() << endl;
    }
ios_base::failureThis is reported for  underlying file system related exceptions with error_code 

Example
    /*prints
    Exception caught (ios_base::failure):
    Value: 1 (io_errc::stream)
    Category: iostream
    Message: iostream error
    */
    promise<int> prom;

    try 
    {
        //throws error because file name is invalid
        ifstream("doesn't exist").exceptions(ifstream::failbit);
    }
    catch (ios_base::failure& e) 
    {
        error_condition cond = e.code().default_error_condition();
        cerr << "Exception caught (ios_base::failure):" << endl;
        cerr << "Value: " << cond.value() << endl;
        cerr << "Category: " << cond.category().name() << endl;
        cerr << "Message: " << cond.message() << endl;
    }


No comments:

Post a Comment