2012-09-25 29 views
6

Windows実行時の型がCOMエラーを発生させた場合.NETはExceptionインスタンスにこのエラーを頻繁に(または常に?)ラップするようです。エラーメッセージには、COM HRESULTエラーコードが含まれています。例えばAES-CBCで新しいCryptographic APIを使用する場合、バッファ長が間違っていると、「指定されたユーザバッファは要求された操作(Exception from HRESULT: 0x800706F8)に対して有効ではありません」というメッセージとともにExceptionになります。例外が発生するWinRT例外を処理する方法は?

さて、これらの例外をどうやって処理するのですか?私たちは例外からどのような種類の例外であるかを知るためにHRESULTコードを読みますか?古典的な.NETで私はCryptographicException私は他のエラーと暗号のエラーを区別するために使用することができます。

私が理解していない別のことは、Microsoftのコード品質ルールでは、Exceptionをスローしないで常に型を派生させるべきだということです。その理由は、OutOfMemoryExceptionのようなより多くの致命的な例外をキャッチする一般のExceptionに誰も遭遇しないように強制されなければならないからです。もう1つのルールでは、決してライブでExceptioを捕まえるべきではないと言います。 Windows StoreアプリケーションまたはWinRTライブラリでExceptionを強制的に取得するように強制すると、これらのポリシーに従うことができますか?

ところで:Clemens Vasters shows in his blog how we can catch Exception while avoiding to catch fatal exception。私はキャッチExceptionはもはや悪いコードではないと仮定します。

+0

リンクされたブログエントリに関して、リストされた「致命的な」例外の多くは、マネージコードによって捕らえられません。注目すべきは、「StackOverflowException」ですが、私はAVsが捕まえられないことはかなり確信しています(どちらもネイティブコードで捕らえることができますが、そうすることは危険です)。 _appear_finalが実際にそうでないかもしれないいくつかの例外もあることに注意してください。たとえば、多くのCOMコンポーネントは、特定のバッファ内の領域が使い果たされたときに 'E_OUTOFMEMORY'を返します。このHRESULTはOutOfMemoryExceptionとして変換されますが、プロセスがそのアドレス空間全体を使い果たしているわけではありません。 –

答えて

4

Exceptionを捕捉し、特定のエラーを処理するには、HRESULTをオンにして、エラーが「予期しない」場合はExceptionを再投入することができます。例えば、

try 
{ 
    // ... 
} 
catch (Exception ex) 
{ 
    switch (ex->HResult) 
    { 
    case E_INVALID_USER_BUFFER: // 0x800706f8 
     // handle invalid buffer case... 
     break; 
    default: 
     // Unexpected exception; re-throw: 
     throw; 
    } 
} 

は(私は無効なバッファを提供することはより多くのランタイムエラーよりも論理エラーのように聞こえることに注意してしまうので、私は、この特定の例外は実際にキャッチする必要があるのだろうか。)

を別の方法として、より一般的な解決策は、既知のHRESULTに対してExceptionを処理する関数または一連の関数を記述し、より具体的な例外を再スローすることです。たとえば、

static void HandleKnownExceptions(Action f) 
{ 
    try 
    { 
     f(); 
    } 
    catch (Exception ex) 
    { 
     // Detect expected HRESULTs and throw the more-specific exception 
     // type for each. 
    } 
} 

これらのアプローチはどちらもC++とC#の両方で同等に機能します。

Exceptionがプラットフォームまたは他のコンポーネントによって直接スローされるとは限りません。 WindowsランタイムABIレイヤーには、例外はありません。すべてのエラーは、HRESULTによってABI境界にレポートされます。 CLRは、いくつかの既知のHRESULTをより特定の例外タイプに変換しますが、一般的な変換は実行できません。

+0

ありがとうございました。それは無効なバッファHRESULTをキャッチするとき私のアプローチでした。 .NETプログラマがHRESULTSに対処しなければならないというのはちょっと奇妙なことが分かります。無効になった可能性のある無効なデータを復号しようとすると、簡単に無効なバッファを取得することがあります。暗号化されたデータを適切な長さでチェックすることは、使用されているアルゴリズムとキーに依存するため、ほとんど不可能と思います。使用されたブロックサイズを知ることはすでに難しいです。無効なデータをユーザーフレンドリーに扱うためには、無効なバッファー・エラーをキャッチすることが不可欠です。 –

+0

ああ、私の間違い。バッファーが無効だったものが誤解されました。あなたは間違いなくそのようなエラーを処理するのが良い考えです:-) –

関連する問題