質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • C#

    7444questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • VB.NET

    943questions

    Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

  • 例外

    31questions

    例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外時のログ出力、エラーダイアログ表示の制御について

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,540

yougo0411

score 6

VB.Net(C# でも)で、例外エラー時のログ出力、ダイアログ表示についてご意見をお聞かせください。

実現したい事は以下になります。
・エラーダイアログ:エラーが発生したメソッドで例外をcatchしてダイアログ表示する。
・ログ出力:各メソッドでは例外を再throw または catchしないでイベントハンドラーとなるメソッドでcatchしてログ出力する。
 (エラー発生メソッドからイベントハンドラーまでの階層的なスタックトレースをログに出力する為)
・例外時にエラーダイアログの表示は1度のみとする。

ここで問題になっているのが、
・trycatchを記述していないメソッドで例外発生時に自メソッドでエラーダイアログ表示されずに、
 イベントハンドラーでログ出力のみ、となってしまうことです。

各メソッでは例外に対して適切なエラー内容を表示したいので、
イベントハンドラーでpublicな「ダイアログ表示済みフラグ」などを設けて判定することは避けたいです。
(フラグの初期化漏れとかもあるので)
また、全てのメソッドにtrycatchを実装することも避けたいのです。

★画面
Sub button1_Click() Handles Button1.Click
  Try
    共通クラス.データ取得処理()
    Dim ii AS Integer = (1/0) '←★MSG出力・ログ出力!
  Catch(ex As DivideByZeroException)
    MSG("0割りエラー")
    ログ出力()
  Catch(ex As Exception)
    ログ出力()
  End Try
End Sub

★共通クラス
'trycatchを実装しない(想定していない)メソッド
Sub データ取得()
    ~DB接続ロジック~ '←★ログ出力しかされない

    マスタ取得処理()
End Sub
Sub マスタ取得処理()
  Try
    ~SQL実行ロジック~    '←★MSG出力・ログ出力!
  Catch(ex As SqlException)
    MSG("SQLエラー")
    Throw
  End Try
End Sub

案としては、
『イベント開始時にpublicなエラー情報保持クラスを生成して、各メソッドで例外エラーが設定された場合に、
イベントハンドラー側でログ出力・ダイアログ表示させる』、が思いついたのですが、
そもそも生成した保持クラスに万人がアクセスできる為にはどこで実装すればいいのか。。(インスタンスを引数として引き回すしかないのか?)

オブジェクト指向などを考慮して実装すると上記問題は解決したりするのでしょうか。
オブジェクト指向でなくても構わないのでテクニック等あればご教授ください。

宜しくお願いしします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+1

こんにちは。

まず、ログを出力しているのですから、アプリケーションの利用者へはエラーが発生したことのみを通知すれば良いのではないでしょうかね。
詳細な情報はログへ出力すれば良いと思います。
極まれにツール的なものでアプリケーション利用者へダイレクトにエラー内容を伝えるべきケースがあるかもしれませんが、その場合は逆に例外を使用するのでなく適切なエラー判定を実装するべきかもしれません。(コード例であれば例外で補足するよりもゼロ除算をしていないかどうかのチェックを入れたほうが良いです。)

また、各処理でメッセージボックスとして表示する内容ですが、コード例のものだとあまり意味がないものになっていると思います。

以上を踏まえますとメッセージボックス表示箇所はどこかにまとめて良いと思います。
とりあえず、処理の起点となるイベントハンドラなど。
ログに出力する際は例外のMessageとStackTraceも出力したほうが良いでしょう。
e.ToString()をそのままログ出力するのが一般的だと思います。
スタックトレースからどのメソッドでどういう原因でエラーが発生したのかわかるはずです。

ログを各メソッドで出力するかルートで出力するかは設計次第ですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/27 23:34

    ご回答有難うございます。
    確かに例外エラー通知は続行不可能であることをユーザに通知する、という観点であれば、イベントハンドラか、エントリポイントでApplication_ThreadException()を実装して同じエラー文言、でも良いのかもしれません。
    アドバイス内容の線を含めて再検討したいと思います。

    キャンセル

+1

共通クラスとやらがダイアログ出しているのが気持ち悪いです。
共通クラスが本来の仕事とユーザーへの通知という2つのことを担ってしまっています。
画面に近い奴が共通クラス諸々の出した例外を受けてダイアログ出すのが自然では?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

・エラーダイアログを誰に見せたいのか
・それを見た人に何を期待するのか

デバッグ用にダイアログ出したいわけじゃないんですよね?
ダイアログ表示の要/不要を検討した方がいいんじゃないかなあ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/27 22:17

    ご回答ありがとうございます!
    エラーダイアログはデバッグ用ではありません。
    例えば、DB接続時のエラーは"DB接続エラー"、SQL実行のエラーは"SQL実行エラー"と出力するのですが、詳細なダイアログ(含むメッセージID)を出したい場合は、自メソッドの例外処理で書かないものですか?
    遷移の大本にグローバル変数などで渡すのが一般的でしょうか?

    キャンセル

  • 2016/04/27 22:35

    言語や環境によって「やりやすい」形は違うと思いますが…
    エラーが発生したらログで調べるやり方が多かったので
    一般的なやり方というと… どうでしょう?
    プロジェクトの方針や利用者からの要求でそういう風に
    して欲しいというのなら、やるんでしょうねえ。

    キャンセル

  • 2016/04/27 23:17

    確かに要件による処も多いと思います。
    各メソッドで独自のエラーダイアログが必要かどうかを含め、再検討を考えてみます。

    キャンセル

0

ログ出力は大元で一元管理しているのに、メッセージは大元で表示したり各Catchで表示したりしているので統一性がないように感じるのかも?
どちらかに統一すればすっきりしそうです。

案①:ログは大元で出力、メッセージは必要な個所でTry~Catchして出力する
案②:ログもメッセージも大元で一括出力する

自分は案①で実装するケースが多いです。
案②を採用する場合、例えばPublicなエラー情報管理クラスを用意し、各所のCatch処理で
・エラーの発生メソッド
・エラー情報
・メッセージ内容(固有のメッセージを表示する場合)
などの情報を格納してThrowする。
その例外を大元でCatchして、エラー情報管理クラスを見ながらメッセージ表示する、といった感じでしょうか。

参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/27 23:04

    ご回答ありがとうございます。

    案②の場合、全てのメソッドに専用の引数を用意して「エラー情報管理クラス」のインスタンスを引き回す、というイメージでよいですか?

    キャンセル

  • 2016/04/28 13:20

    自分が案②で実装した際はモジュール内のどこからでも参照できるクラスで実装しました。
    それが美しいとは思いませんでしたが...(^-^;

    キャンセル

0

こんにちは。

昔、似た問題に悩んで、結局、ダイアログ表示済フラグで逃げた記憶が有ります。

その時は、下記ケースだったように記憶しています。
①処理をユーザへ問い合わせるケースでその選択結果をログに残し、例外は投げない。
②処理を継続できないようなエラーが発生し、その旨の詳細をユーザへ通知後、例外を投げて、ログ記録。
③想定外のエラーが発生し、ログへ記録は残せるが、突然処理が中断するのでよろしくない。最低限のダイアログを出したいが、下手に出すと②とかぶる。

本来は③が発生しないようにするべきなのですが、少ない工数をやりくりしている関係上どうしても防げなかったケースでした。(頻発しなければ許されるようなアプリでした。)
意図的に投げる例外は必ず独自の例外としていたので、それにダイアログ表示済フラグを追加したような記憶があります。ここなら初期化漏れありえませんので。
知らない例外なら、無条件でダイアログ表示しても良いですし。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    7444questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • VB.NET

    943questions

    Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

  • 例外

    31questions

    例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。