TOP
PROFILE
MUSIC TUNE
BBS
LINK

2004年12月30日

例外の怪

先日例外処理で妙な現象にぶちあたった。
というのは開発がASP.NET、つまりWebアプリであればGlobal.asaxのApplication_Error等でキャッチ漏れの例外などを一元管理が出来るし、ページ単位であればPage毎にPage_Errorイベントハンドラを定義すれば同様の管理が可能である。
これと同じことをWindowsフォームでやろうと思い、やや強引ではあるがエントリポイントであるMainメソッドの中に例外処理を埋め込んでいたわけ、まぁどうせApplication.Run()で全て始まるのだから、キャッチ漏れの例外は最終的にはここまで上がってくるだろうとの読みからなわけで、実際に開発段階ではうまくログ出力もメッセージの表示も出来てたのだ。
が、いざインストーラを作ってシステムテストをはじめると不思議と例外処理がされずにアサートが出る始末・・ただ問題はこれがVisualStudioから起動する分には問題なくキャッチされているから訳が分からない。
対応としてThreadException、UnhandleExceptionイベントのハンドラを登録することで解決したわけだが、問題は何故にVisualStudioからの起動であればエントリポイントまで例外が上がってくるのに、何故にexeから直接起動するとアサートがでるのかという点。

開発中のシステムはファイルの更新が特殊で、アプリの起動時に特定のフォルダにあるアセンブリと更新情報を比較して新しければコピーし実行時に動的バインドを行う仕組みになっており (その為一切の参照設定をせずに、アプリの起動とアセンブリの更新のみを行うランチャを用意している) それが影響しているのかと思ったのだが、簡単なサンプルでも同様の問題が発生する始末・・話がそれるがあくまでサーバーがWebLogicであった為にノータッチデプロイメントは論外なので、こういう仕様になったわけ。
まぁお客さんはどこで情報を仕入れたのか、マルチモジュールアセンブリでは?と当時言ってきたが、それはまったく用途が違うし、リソース分割してるわけでも、異開発言語でクライアント作ってるわけでもないし、そもそも更新処理の根本は同じだっちゅうの!と軽く一蹴。

余談だが、上記の理由からこのアプリは複数のプロジェクトで構成されている (ApplicationLogic、BusinessEntity、ApplicationBlock等) のだが、開発技術大全vol4では細かくプロジェクトに分割することについて否定されていた。
自分も同意見ではあるけど、これはエンドさんのご要望であると弁明(^^;

んで話を戻してちょっと気になったので調べたところ・・
現在のメソッドで一致するブロックが検出されないと、ランタイムはスタック内で現在のメソッドの呼び出し元を 1 つずつ検索します。どの呼び出し元にも一致するブロックがない場合には、デバッガが例外へアクセスできます。デバッガが例外にアタッチされていない場合には、UnhandledException イベントが発生します。UnhandledException イベントのリスナがない場合、ランタイムはスタック トレースをダンプし、プログラムを終了します。
との記述をMSDNで見つけた。
ようするにデバッガがアタッチ出来るかどうかが影響していたということだろうか?と勝手に納得。

ただ障害票に理由を説明するのが面倒やけど・・

いやまぁ
「例外はしっかりと然るべき場所、タイミングで処理しましょう」
ってことが本筋なんですけどね。

Posted by GAMMARAY at 2004年12月30日 17:41 | TrackBack
Comments
Post a comment









Remember personal info?