- PR -

Try Catch文とThrowについて

投稿者投稿内容
ジン
常連さん
会議室デビュー日: 2008/07/22
投稿数: 33
投稿日時: 2008-09-11 20:19
VB2005で開発しています。

1つの処理(登録ボタン押下など)をメソッドなどで行うと思うのですが、
ユーザーへのエラーメッセージの表示を1度に済ませたいと思っています。
そこで以下のようなプログラム設計をしたのですが、
問題ないか確認させて下さい。

最上位のメソッド以外のメソッドはすべてTry Catch文を使用し、
例外がCatchされた場合は、そのままThrowする。
その上位のメソッドでもそのままThrowし、
最上位メソッドでCatchしエラーメッセージを表示する。

以上のようなプログラムを作成しようと思っているのですが、
この設計思想に、大きな問題などございますでしょうか?

簡単なプログラムを作成して、
複数回Throwすることに問題がないことを確認しましたので、
これで大丈夫と私は判断したのですが。。。

もし欠陥がありましたら、ご指摘頂きたいです。
ぜひ、よろしくお願いいたします。
さかもと
ぬし
会議室デビュー日: 2004/05/14
投稿数: 586
投稿日時: 2008-09-11 21:51
さかもとと申します。

そもそも「登録」のような処理自体を業務上のエラーとせず、「例外」として投げること自体が設計思想としてどうかと思います。(処理内容を詳しく知って書いているわけではありません)

なんでもかんでも「例外」で投げるよりは、極力仕様上のエラーを拾っておいて、どうしても拾いきれないものだけ例外とすべきではないでしょうか。


_________________
------------------------------------------
拝啓、さかもとと申します♪
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2008-09-11 22:16
引用:
最上位のメソッド以外のメソッドはすべてTry Catch文を使用し、
例外がCatchされた場合は、そのままThrowする。

だったら最上位のメソッド以外ではcatchしなければいいんじゃないですか?

http://msdn.microsoft.com/ja-jp/library/system.exception(VS.80).aspx
「例外をスローしたり処理したりするときには、大量のシステム リソースおよび実行時間が使われます。」
まさる
ベテラン
会議室デビュー日: 2006/12/21
投稿数: 59
お住まい・勤務地: 越後の中ほど
投稿日時: 2008-09-11 22:17
引用:

ジンさんの書き込み (2008-09-11 20:19) より:
最上位のメソッド以外のメソッドはすべてTry Catch文を使用し、
例外がCatchされた場合は、そのままThrowする。
その上位のメソッドでもそのままThrowし、
最上位メソッドでCatchしエラーメッセージを表示する。



そもそも、ただThrowする「だけ」のTry Catchなら、最初から書かない方が良いですよ。

参考:NAL-6295の舌先三寸「むやみにキャッチしないでね。ゴールキーパー以外はハンドで反則ですよ。」
http://d.hatena.ne.jp/NAL-6295/20050909/p1
otf
ベテラン
会議室デビュー日: 2006/08/04
投稿数: 91
投稿日時: 2008-09-11 23:48
例外が投げられたメソッド内でCatchがなければ自動的に上位メソッドに伝搬されます。
わざわざ自分でリスロー(再びThrow)する必要はありません。
引用:

さかもとさんの書き込み (2008-09-11 21:51) より:
そもそも「登録」のような処理自体を業務上のエラーとせず、「例外」として投げること自体が設計思想としてどうかと思います。(処理内容を詳しく知って書いているわけではありません)


「登録」という処理(メソッド)の事後条件は「正しく登録されていること」であり、その事後条件を達成できないのなら例外を投げるべきだと思います。

↓こういう例外(プログラミングじゃないほうの例外)もあります。
http://msdn.microsoft.com/ja-jp/library/ms229009(VS.80).aspx
さかもと
ぬし
会議室デビュー日: 2004/05/14
投稿数: 586
投稿日時: 2008-09-12 08:08
さかもとです。

引用:

「登録」という処理(メソッド)の事後条件は「正しく登録されていること」であり、その事後条件を達成できないのなら例外を投げるべきだと思います。




当初書いたのは、ジンさんの質問内容を例えば・・・・。

1:登録ボタンを押す

2:既にそのレコードが存在する

3:例外

と言ったように、1,2の間で「存在確認」を行わずとりあえず例外として上に放り投げることを言っているのかな?と思い、極力業務上潰せるエラーは潰しておいてから、例えばDBなどへの最終更新時にサーバーが落ちていて登録できなかったなど、そういう部分だけ例外として拾うべきかなと思い書いてあります。

>>ユーザーへのエラーメッセージの表示を1度に済ませたいと思っています

この部分のエラーメッセージが「システム的なエラーメッセージ」というより「業務上のエラーメッセージ」に読めたもので。



_________________
------------------------------------------
拝啓、さかもとと申します♪
otf
ベテラン
会議室デビュー日: 2006/08/04
投稿数: 91
投稿日時: 2008-09-12 08:37
引用:

さかもとさんの書き込み (2008-09-12 08:08) より:

当初書いたのは、ジンさんの質問内容を例えば・・・・。

1:登録ボタンを押す

2:既にそのレコードが存在する

3:例外

と言ったように、1,2の間で「存在確認」を行わずとりあえず例外として上に放り投げることを言っているのかな?と思い、極力業務上潰せるエラーは潰しておいてから、例えばDBなどへの最終更新時にサーバーが落ちていて登録できなかったなど、そういう部分だけ例外として拾うべきかなと思い書いてあります。


業務エラーは例外にするなといってるのかと思いました。
「登録」処理を実行する前に業務エラーを検証しておくということですね。
私もその方がいいと思います
ジン
常連さん
会議室デビュー日: 2008/07/22
投稿数: 33
投稿日時: 2008-09-12 10:12
皆様ご回答ありがとうございます。

業務上のエラーであればThrowしないほうが良いのですね。
実行時間がかかり、システムリソースも大量に使われるのであれば、
なおさらですね。
とても勉強になりました。


もともと何を行いたかったかと言いますと、
ネットワークが切れていたり、サーバーが落ちていたりした
ような場合に、例外をキャッチし、各メソッドでログを出力し、
最上位のイベントに限り、メッセージボックスを表示しようと考えておりました。
(どのような経路でエラーが発生したかを知りたいため、
 上位のメソッドでもログを出力します。)


この私の要件を満たすためには、各メソッドでTry Catchを行い、
例外をキャッチした場合は、上位メソッドにThrowではなく、戻り値などを使用して
「成功」、「失敗」などの情報を返すのが適切ということでしょうか?
(例外クラスを自分で作成して、Throwするべきなのだと勘違いしていました。)


>参考:NAL-6295の舌先三寸「むやみにキャッチしないでね。ゴールキーパー以外はハンドで反則ですよ。」
>http://d.hatena.ne.jp/NAL-6295/20050909/p1
またご紹介頂いたページに関する質問で申し訳ないのですが、
Appication_Errorで一元管理するということですが、
この「Appication_Error」とは何を指しているのでしょうか?
「MyApplication」クラスのことではないですよね?
私はWindowsアプリケーションを作成しています。
検索して、以下のページなども見たのですが、うまく理解できませんでした。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?mode=viewtopic&topic=25373&forum=7
もしよろしければ、教えて頂けませんか?


ぜひ、お願いいたします。

スキルアップ/キャリアアップ(JOB@IT)