Stack error with std :: error_code

For error handling, exceptions are problematic for me because my code will be a dynamically linked library. In addition, I believe that exceptions should be used only in exceptional cases. But I will have cases where an error may occur that is not exceptional. Another problem is that my library will be called from C #. Therefore, using exceptions for all errors does not seem to be the right choice.

But I find the concepts std :: error_code and std :: error_category quite enjoyable and would like to use it in my application. However, I would also like to suggest some stack trace for errors.

Consider an example: A user wants to load a domain object from a database. To load this domain object, the application must load rows from different tables. Suppose that one of the required rows was not found. In this case, the database level will generate some "not found" error. If I pass this error to all users, the error message will not be very useful, because no one knows what was not found. Similarly, if each layer handles lower-level errors and generates a corresponding new error, abstracting the low-level error, I get something like "cannot be loaded from the database", which again is not very useful. I would like them both. This each level abstracts the errors that it receives from any lower level,in order to be able to display descriptive messages to the end user, but at the same time I do not want to lose low-level error information. So I would like to have something like trace stack errors.

I thought about the output from std :: error_code and extended the class with a pointer to the base std :: error_code and methods to get all of these base objects. However, I'm not sure if this technique was a good idea, because I read that when designing std :: error_code, care was taken into account to make it effective.

We want error_code to be a type of value that can be copied without slicing and without the need for heap distribution, but we also want it to have polymorphic behavior based on the category of errors.

EDIT Now I think this method can also lead to shear problems, right?

2 , , std:: error_code. , -, boost:: optional. , . boost:: optional . - , , , std:: error_code , , . , std:: error_code , .

3 , , boost:: optional. , .

+3
1

, std::error_code. , . wrap() , , , . , . getter . , . , , , . std::error_code.


class my_error : public std::error_code
{
public:
    my_error() : std::error_code(), m_innerError(NULL) {};
    my_error( int val, const std::error_category & cat ) : std::error_code(val, cat), m_innerError(NULL) {};
    my_error( std::error_code & error ) : std::error_code(error), m_innerError(NULL) {};
    my_error( const std::error_code & error ) : std::error_code(error), m_innerError(NULL) {};
    ~my_error()
    {
        delete m_innerError;
    }

    template <class ErrorCodeEnum>
    my_error(ErrorCodeEnum e,
                   typename boost::enable_if<std::is_error_code_enum<ErrorCodeEnum> >::type* = 0)
    {
        *this = make_custom_error(e);
    }

    template<typename ErrorCodeEnum>
    typename boost::enable_if<std::is_error_code_enum<ErrorCodeEnum>, error_code>::type &
    operator=( ErrorCodeEnum val )
    {
        *this = make_custom_error(val);
        return *this;
    }

    my_error const * get_inner() const
    {
        return m_innerError;
    };

    void wrap( const my_error & error)
    {
        m_innerError = new my_error(error);
    };

private:
    my_error * m_innerError;
};
+1

All Articles