是否可以使用GetLastError检查是否已重试错误代码

时间:2013-09-17 09:52:13

标签: c++ winapi

如果你有一个大型系统自动显示一个很好的窗口来解释捕获的异常,那么能够将错误代码与消息一起呈现(以便进一步调查)会很不错。但是由于一些函数调用是失败的windows函数,它设置了错误代码,有些是本地失败函数,没有设置错误代码,我想知道是否有办法检查是否已“检索到最后设置的错误代码” “已经。

假设我们有一段代码

if (!CopyFile(("c:\foobar.txt", "d:\foobar.txt",FALSE))
{
  throw FooBarException("bla bla bla");
}

这里可以自动将错误代码添加到错误消息中,因为CopyFile是一个在失败时设置错误代码的函数。现在,我们可以在if语句中添加“手动”错误代码,并将其附加到创建异常时传递的错误字符串。但是为了不必更改现有代码中的数千个位置,我们可以让 FooBarException 的构造函数自动获取并附加错误代码。但这也引发了有争议的问题。

如果某些未设置错误代码的代码导致引发 FooBarException ,该怎么办?然后构造函数会 GetLastError ,但会得到一个可能根本没有连接到当前异常的错误代码。

但是如果 FooBarException 的构造函数可以调用一些 LastErrorRetrived (或类似的东西)并且如果已经检索到错误代码则获取 true 在它应该忽略附加错误代码并假设它与之前的错误相关联之前。

现在我明白如果在每个可能失败的窗口函数和设置错误代码之后实际上没有“检索”错误代码,这可能会变得混乱。但我们假设已经完成了。

2 个答案:

答案 0 :(得分:2)

简短回答:不。

GetLastError返回的值只是一个没有任何逻辑附加的全局(每个线程)对象。可以通过GetLastErrorSetLastError和神秘的RestoreLastError访问它。

我担心我必须打破这个消息:将错误处理改造成一个没有为它做好准备的系统是乏味的。

除了实现几个异常类(对于Win32错误代码,COM HRESULT等)并更改每次调用之外,你几乎无能为力。

答案 1 :(得分:1)

GetLastError()只获取线程的最后错误代码值,这就是全部。所以,我相信没有办法知道它被称为一次或几次。而且,我真的认为你不需要。

这里最好的解决方案是创建从某个基类派生的 WinAPIException 类(例如, std :: exception )。在构造函数中, WinAPIException 应该在任何其他WinAPI调用之前调用GetLastError()。它保证错误值不会改变。

if( !CopyFile("c:\foobar.txt", "d:\foobar.txt",FALSE) )
    throw WinAPIException("Houston, we have a WINAPI problem");

如果在非WinAPI函数调用后检查结果 - 只需使用其他异常类(派生自相同的基类):

if( std::cin.get() < 0 )
    throw std::runtime_error("Houston, we have runtime problem");

因此,您可以使用单个try ... catch语句来捕获两个异常:

try {
    ...
} catch( std::exception &e ) {
    ...
}