正确使用例外

时间:2014-06-18 11:51:49

标签: java c# c++ exception callstack

我不确定是否应该采用例外的方式。我经常想知道"我是否必须在此处捕获此信息,或者在调用堆栈中是否更高?"和那样的事情。但我已经创建了一个小的异常类,以获得某种类似C#的异常,它可以显示一堆异常:

class Exception : public std::exception
{
protected:

   std::string _trace;

public:

   Exception()
    : _trace( "[ERROR - " + (std::string) DateTime() + "]"
   { }

   Exception & push( const std::string & msg )
   {
      this->_trace += '\n\t' + msg;
      return *this;
   }

   virtual const char * what() const
   {
      return this->_trace.c_str();
   }
};

我可以这样使用:

function depth0()
{
    try
    {
        depth1();
    }
    catch( Exception & exc )
    {
        throw exc.push( "depth0() - Failed." );
    }
}

function depth1()
{
    try
    {
        depth2();
    }
    catch( Exception & exc )
    {
        throw exc.push( "depth1() - Failed." );
    }
}

function depth2()
{
    try
    {
        depth3();
    }
    catch( Exception & exc )
    {
        throw exc.push( "depth2() - Failed." );
    }
}

function depth3()
{
    if( something goes wrong )
    {
        throw Exception().push( "depth3() - Failed." );
    }
}

try
{
    depth0();
}
catch( Exception & exc )
{
    std::cout << exc.what() << std::endl;
}

我不必抓住并抛出每个深度的callstack,这只是一个例子。

这是使用例外的正确方法吗?它不反对例外哲学吗? (我还不明白)。

谢谢:)

PS:我使用的是Java和C#标签,因为这一般都是关于异常的,即使样本是用C ++编写的。

1 个答案:

答案 0 :(得分:1)

作为一般规则:捕获可以处理它的异常。并在可能的情况下捕获特定的异常。就像连接到您的数据库一样 - 您永远不会想要向用户弹出异常 - 在最坏的情况下包含连接字符串详细信息。因此,您的业务逻辑层必须捕获数据库异常并尽可能地处理它(再次尝试连接,记录异常等)并抛出前端可以保存处理的一些异常(自定义数据库连接异常或其他没有详细说明) )。

另一方面,你无法处理好的事情(内存异常等)你可以在应用程序级别捕获并回复一些(自定义,但至少是通用的)信息给用户出错的地方。如果可能,使应用程序进入稳定状态。