1

This is a (modified) problem from a test last week. I was given an exception class with a predefined number in it:

class ErrorException  {

    /**
    * Stub class.
    */
private :static long ErrorCode;

public: ErrorException( string str) {
                cout <<str;
        }
};

long ErrorException::ErrorCode = -444;

I think I was supposed to do was catch the exception and then return the number as an error code, but I could not figure out how to get the number in. I could make the catch return a string but not the number as string:

#include "stdafx.h"
#include <iostream>
#include "ErrorException.h"

#include "errno.h""
#include <string>;
class FillerFunction {


public :

        virtual int getFillerFunction(int x) throw (ErrorException) = 0;

} // this notation means getFillerFunction is always throwing ErrorException?

double calculateNumber(int y){
//.....
try{
     if (y !=0){
      throw(ErrorException(?????))
      }
};

double catchError(){
      catch(ErrorException& x);
};

I eventually made it return the string "error" which is no better than using an if statement. I've looked up other catch-throw examples in c++ and dynamic exceptions, but I can't find an example with an exception grabbing a variable defined in the class.How do I access the ErrorCode, save changing the return type of ErrorException()?

  • This is the skeleton of the code I got. What I'm asking is: 1. Why did they give me a number, if I'm not supposed to pass it in, and 2. How would I pass it in? –  Aug 21 '16 at 22:53

2 Answers2

1

Though this question has already been answered, I just want to add a few notes on proper exception handling in C++11:

First, throw(ErrorException) should not be used, as it is deprecated: http://en.cppreference.com/w/cpp/language/except_spec

Also, it is generally advisable to make use of the fact that C++ provides standard exception classes, personally I usually derive from std::runtime_error.

In order to really take advantage of the exception mechanism in C++11, I recommend using std::nested_exception and std::throw_with_nested as described on StackOverflow here and here. Creating a proper exception handler will allow you to get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging. Since you can do this with your derived exception class, you can add a lot of information to such a backtrace! You may also take a look at my MWE on GitHub, where a backtrace would look something like this:

Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
GPMueller
  • 2,881
  • 2
  • 27
  • 36
0

In your throw you're constructing an exception object. If you prefer to pass a number, you must provide the appropriate constructor.

Quick and dirty:

class ErrorException  {

private :
    static long ErrorCode;

public: 
    ErrorException( string str) {
                cerr <<str<<endl;
        }
    ErrorException( long mynumeric code) {
                cerr <<"error "<<mynumericcode<<endl;
        }
};

The catching should look like:

double calculateNumber(int y){
    try {
         if (y !=0){
            throw(ErrorException(227));   
         }
    } catch(ErrorException& x) {
         cout << "Error catched"<<endl; 
    }
 }

Must be elaborated further

It's unusual to to print something in the exception constructor. You'd better populate the information needed in the catch, so that these information could later be accessed with the appropriate getter. The printing would then occur in the exception handler.

If you have a static error code, I suppose that somewhere you have a function that returns the last error code whatever happened. So maybe you'd update this code (but how do you intend to update it with the existing string alternative ?

Here how it could look like:

class ErrorException  {    
private :
    static long LastErrorCode;
    long ErrorCode; 
    string ErrorMessage;     

public: 
    ErrorException(long ec, string str) : ErrorCode(ec), ErrorMessage(str) 
        {
                LastErrorCode = ec; 
        }
    static long getLastError() const { return LastErrorCode; }  // would never be reset
    long getError() const { return ErrorCode;  }
    string getMessage() const { return ErrorMessage; }
};

The catching should look like:

double calculateNumber(int y){
    try {
         if (y !=0){
            throw(ErrorException(227,"y is not 0"));   
         }
    } catch(ErrorException& x) {
         cerr << "Error "<<x.getError()<<" : "<<x.getMesssage()<<endl; 
    }
    cout << "Last error ever generated, if any: " << ErrorException::getLastErrror()<<endl;
 }

Neverthesess, I'd advise you to have a look at std::exception before reinventing the wheel.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • 1
    Thank you, this helped a lot. I was very confused. –  Aug 21 '16 at 22:54
  • @user49157 no problem. About the hidden question in the comment, the exception specification are deprecated (see also http://stackoverflow.com/a/11258734/3723423), except for `noexcept` (see http://en.cppreference.com/w/cpp/language/noexcept_spec) – Christophe Aug 21 '16 at 23:16