Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is that a good idea to define exception with template?

I am thinking is that a good idea to define exception with template. Defining different types of exception is a super verbose task. You have to inherit exception, there is nothing changed, just inherit. Like this..

class FooException : public BaseException {
public:
    ...
};

class BarException : public BaseException {
public:
    ...
};

...

That's a nightmare isn't it? So I am considering to define different exception with template

/**
    @brief Exception of radio
**/
class Exception : public runtime_error {
private:
    /// Name of file that throw
    const string m_FileName;

    /// Line number of file that throw
    size_t m_Line;
public:
    Exception(const string &what, const string &File, size_t Line)
throw()
        : runtime_error(what),
        m_FileName(File),
        m_Line(Line)
    {}

    virtual ~Exception() throw() {}

    /**
        @brief Get name of file that throw
        @return Name of file that throw
    **/
    virtual const string getFileName() const throw() {
        return m_FileName;
    }

    /**
        @brief Get throw exception line
        @return Throw exception line
    **/
    virtual size_t getLine() const throw() {
        return m_Line;
    }

    /**
        @brief Get description of this exception
        @return Description of this exception
    **/
    virtual const string getMessage() const throw() {
        return what();
    }

    virtual void print(ostream &stream = cerr) const throw() {
        stream << "# RunTimeError #" << endl;
        stream << "Error : " << what() << endl;
        stream << "File : " << getFileName() << endl;
        stream << "Line : " << getLine() << endl;
    }
};


/**
    @brief Template exception of radio
**/
template <typename T>
class TemplateException : public Exception {
public:
    TemplateException (const string &what, const string &File, size_t
Line) throw()
        : Exception(what, File, Line)
    {}

    virtual ~TemplateException () throw() {}
};

}

#define THROW(type, error) (throw TemplateRadioException<type>(
(error), __FILE__, __LINE__))

So if I have to define a new exception, I can just define a empty class like this.

class NuclearException {};

To throw exception

THROW(NuclearException , "Boom!!");

To catch

try {

} catch (TemplateException<NuclearException> &e) {
    // ...
}

If we want to catch all exception, we can write this

try {

} catch (Exception &e) {
   // ...
}

It works fine, but I don't sure are there any side effects? Is this a good idea to define different type of exception? Or there is better solution? I have no idea :S

Thanks. Victor Lin.

like image 987
Fang-Pen Lin Avatar asked Jan 20 '09 16:01

Fang-Pen Lin


2 Answers

It's an interesting idea, but apart from the drawbacks already pointed out, it would also not allow you to define an exception hierarchy: suppose that you want to define

class InvalidArgumentException {};
class NullPointerException : public InvalidArgumentException {};

then a TemplatedException<NullPointerException> would not inherit from TemplatedException<InvalidArgumentException>, and your exception handling mechanism might end up being more clumsy than the "plain" one.

like image 53
Paolo Tedesco Avatar answered Sep 20 '22 10:09

Paolo Tedesco


It's definitely possible and works fine, but i would avoid it. It obscures diagnostics. GCC will display the name of the exception type, with the usual template stuff included. I would take the few minutes to define the new exception class, personally. It's not like you would do it all the time.

like image 45
Johannes Schaub - litb Avatar answered Sep 19 '22 10:09

Johannes Schaub - litb