Dim*_* C. 4 c++ logging exception-handling exception
在编写函数时,我的实现经常看起来像这样:
关键部分是伐木.每个失败的函数都应该在日志中添加简短描述.这样,在处理异常的级别,可以向用户显示详细的错误消息.
例如,考虑一个可以创建新用户帐户的应用程序,并且数据库连接存在问题.以下反向堆栈跟踪结果:
使用例外功能,我将按如下方式实现:
void CreateUser()
{
try {
OpenDatabaseConnection();
}
catch(std::exception& e) {
e.AddLog("Failed to create the new user");
throw;
}
//...
}
Run Code Online (Sandbox Code Playgroud)
使用简单的返回值,我写下以下内容:
bool CreateUser(Log& log)
{
if (!OpenDatabaseConnection(log))
{
log.Add("Failed to create the new user");
return false;
}
//...
return true;
}
Run Code Online (Sandbox Code Playgroud)
我发现两种实现都同样好.因此,我没有看到使用异常的优势.我很清楚异常处理通常被认为是一个有用的功能,但我真的不明白为什么.很久以前,我广泛使用异常处理,但我没有看到它的大优势,所以现在我再也不用它了.因此我的问题:
注意:我使用术语日志记录 "收集对错误的解释,以便稍后可以将其呈现给用户".我宁愿不将该解释存储在日志消息的全局集合中(在内存中,在文件中或在数据库中),因为它直接描述了特定的异常.
更新:感谢您的回复.我知道只有当用户不需要有关错误的详细反馈时,例外才有用.(如果我误解了这个,请纠正我.)
您的策略似乎避免了异常的最有用方面,您可以抛出一个异常类,其中已经包含日志信息的文本 - 这是在异常被抛出时生成日志的文本而不是异常时被抓住了.然后你不必抓住每个级别上升到堆栈,但只在顶层.
因此,只有一个try块和一个log.add - 一般来说代码少得多.这样的东西似乎删除了所有的复制.
void OpenDatabaseConnection()
{
if (Error) throw MyException("Failed opening database");
}
void CreateUser()
{
try {
OpenDatabaseConnection();
//...... do everything here
}
catch(MyException& E) { //only one copy of this code
E.AddLog(E.getMessage());
throw;
}
}
Run Code Online (Sandbox Code Playgroud)