问题描述
如果Windows运行时类型引发了COM错误,.NET似乎经常(或总是?)将此错误包含在异常
实例中。该错误消息包括COM HRESULT错误代码。当使用新的加密API与AES-CBC例如错误的缓冲区长度导致异常
,并显示消息提供的用户缓冲区对于请求的操作无效( HRESULT的异常:0x800706F8
)。
If a Windows runtime type raises a COM error .NET seems to wrap this error often (or always?) just into an Exception
instance. The error message includes the COM HRESULT error code. When using the new Cryptographic API with AES-CBC for example a wrong buffer length results in an Exception
with the message "The supplied user buffer is not valid for the requested operation. (Exception from HRESULT: 0x800706F8
)".
嗯,我们应该如何处理这些异常?我们应该从异常中读取 HRESULT
代码,以了解什么样的异常?在经典的.NET中,我会得到一个 CryptographicException
,我可以使用它来区分加密错误和其他错误。
Well, How are we supposed to handle those exceptions? Should we read the HRESULT
code from the exception to get an idea what kind of exception that was? In classic .NET I would get a CryptographicException
that I could use to distinguish cryptographic errors from other errors.
另一个我不明白的是,Microsoft代码质量规则规定,不应该抛出异常,而是始终派生类型。原因是没有人应该被迫抓住一般的异常
,它们会捕获更多致命的异常,如 OutOfMemoryException
。另一个规则说,不要在库中捕捉 Exceptio
n。如果我们被迫在Windows Store应用程序或WinRT库中捕获异常
,我们如何遵守这些策略?
Another thing that I do not understand is that the Microsoft code quality rules state that one should never throw Exception but always derived types. The reason is that no one should be forced to catch the general Exception
that catches more fatal exceptions like OutOfMemoryException
as well. Another rule says that one should never, ever catch Exceptio
n in libraries. How could we follow these policies if we are forced to catch Exception
in Windows Store apps or WinRT libraries?
由方式:。我假设捕捉异常
不再是坏代码。
By the way: Clemens Vasters shows in his blog how we can catch Exception while avoiding to catch fatal exception. I assume catching Exception
is no longer bad code then.
推荐答案
有可能捕获异常
,通过打开HRESULT来处理特定错误,并重新抛出异常
如果错误是意外的。例如,
It is possible to catch Exception
, handle particular errors by switching on the HRESULT, and re-throwing the Exception
if the error was "unexpected." For example,
try
{
// ...
}
catch (Exception ex)
{
switch (ex->HResult)
{
case E_INVALID_USER_BUFFER: // 0x800706f8
// handle invalid buffer case...
break;
default:
// Unexpected exception; re-throw:
throw;
}
}
(我会注意到,像一个逻辑错误,而不是一个运行时错误,所以我想知道这个特殊的异常是否应该被捕获。)
(I would note that providing an invalid buffer sounds more like a logic error than a runtime error, so I wonder whether this particular exception should really be caught.)
或者,一个更通用的解决方案是写一个函数或一组为已知的HRESULT处理 Exception
的函数,并重新抛出更具体的异常。例如,
Alternatively, a more general solution would be to write a function or set of functions that handle Exception
for known HRESULTs and re-throws a more specific exception. For example,
static void HandleKnownExceptions(Action f)
{
try
{
f();
}
catch (Exception ex)
{
// Detect expected HRESULTs and throw the more-specific exception
// type for each.
}
}
这两种方法在C ++和C#。
Both of these approaches work equally well in both C++ and C#.
请注意,平台或其他组件直接抛出异常
。在Windows运行时ABI层,没有例外:所有错误都通过HRESULT跨越ABI边界报告。 CLR将少数已知的HRESULT转换为更具体的异常类型,但无法执行常规翻译。
Note that it isn't necessarily the case that Exception
is thrown directly by the platform or other components. At the Windows Runtime ABI layer, there are no exceptions: all errors are reported across the ABI boundary by HRESULT. The CLR translates a handful of known HRESULTs to more specific exception types, but it cannot perform a general translation.
这篇关于如何处理导致异常的WinRT异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!