Differentiate logic_error in C++

Viewed 750

I would like to be able to catch different logic_errors and be able to differentiate them. Can I somehow pass additional parameters to the logical error which to catch later. The idea is that I need to print. Right now I am just catching the default errors that stof can return. "Sorry invalid temperature" or "Sorry invalid rainfall"

P.S. The function stringToTime converts dates to strings and throws logic error with some text, if the date doesn't match certain criteria. Thank you!

    try{
        tm date = stringToTime(year);       
        float temp = stof(temperature);
        float rain = stof(rainfall);
    } 

    catch(logic_error e){
        if( string(e.what()) == "stof"){
            cout << "Sorry wrong arguments for either Temperature or Rainfall" << endl; 
        }else{
            cout << e.what() << endl;
        }
    }
2 Answers

what() text is implementation defined, and GCC only does lazy (but efficient) printing like that. But you can split the extraction into two functions:

float getTemperature(const std::string& temperature) {
    try{
        return std::stof(temperature);
    } 
    catch(std::logic_error& e){
        std::cout << "Sorry wrong argument for Temperature" << std::endl; 
        throw e; //or you can throw a different exception
   }
}

//same for getRainfall()

void validateArguments()
{
    try {
        tm date = stringToTime(year);       
        float temp = getTemperature(temperature);
        float rain = getRainfall(rainfall);
    } catch (std::logic_error& e) {
        if( string(e.what()) == "stof"){
            //no need to print anymore, but you can e.g. ask for arguments again or something
        }else{
            cout << e.what() << endl;
        }
    }

Side note: Consider using your own exception class for throwing from stringToTime (it can be derived from std::logic_error if you prefer, or straight from std::exception). It's safer and compiler-independent way to distinguish different exceptions. Leave exceptions from standard library to standard library.

Pass in parameters as part of the logic_error constructor. As below in the HERE! comment.

/******************************************************************************

Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, PHP, Ruby, 
C#, VB, Perl, Swift, Prolog, Javascript, Pascal, HTML, CSS, JS
Code, Compile, Run and Debug online from anywhere in world.

*******************************************************************************/

// From:  https://stackoverflow.com/questions/61941722/differentiate-logic-error-in-c

#include <stdio.h>
#include <string>
#include <iostream>

using namespace std;

tm stringToTime( string input )
{
    tm retval;
    retval.tm_year = stof( input ) - 1990;
    logic_error e( "stof" );  // HERE!  Is the constructor that can differentiate the logic_error->when() value.
    throw( e );
    return retval;
}

int main()
{
    printf("User defined logic_error example.\n");

    string year = "2020";
    string temperature = "70";
    string rainfall = "1";
    int lineNum = 10;
    string fieldNames[2] = { "temperature", "rainfaill" };

    try{
        tm date = stringToTime(year);       
        float temp = stof(temperature);
        float rain = stof(rainfall);
    } 

    catch(logic_error e){
        if( string( e.what() ) == "stof"){
            cout << "Sorry wrong arguments for either Temperature or Rainfall" << endl; 
        }else{
            cout << e.what() << " on line " << lineNum + 1 << " type " << fieldNames[0] << endl;
        }
    }

    return 0;
}
Related