- PR -

Try の中

投稿者投稿内容
indigo-x
大ベテラン
会議室デビュー日: 2008/02/21
投稿数: 207
お住まい・勤務地: 太陽の塔近く
投稿日時: 2008-03-04 17:14

ソフトウェアが落ちない限り。

(2重でMsgBoxが表示される等)余り、過剰反応する必要はないと思います。

運用開始時以外、ハッキリ言って例外なんてほとんどでないです。
(出たらえらい事です)

それより、エラーメッセージを丁寧に記述する事が一番です。

(高度なテクニックですが)

NGの例「システムエラーが発生しました」
OKの例「申し訳ございませんが、再度確認の上最初から実行してください」

「最初から」がミソでお客さんはプログラムを再起動してやり直してくれます。
LANVIN
大ベテラン
会議室デビュー日: 2007/03/12
投稿数: 211
投稿日時: 2008-03-04 18:43
みなさんありがとうございます。
確かにindigo-xさんの言われる通りです。

となると

Private Sub Form_Load

Call INIファイルREAD処理
Call ASyori

End Sub
'****
Private Sub ASyori()
Try
処理
Catch ex As Exception
MsgBox("エラー")
End Try
End Sub

でいいのかも。
うーむ
悩むところです。

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2008-03-04 21:58
引用:

LANVINさんの書き込み (2008-03-04 16:08) より:
とにかくエラー処理は
Tryを使おうと思いますが
コード:
Private Sub Form_Load
    Try
        Call INIファイルREAD処理
        Call ASyori
    Catch ex As Exception
        MsgBox("エラー")
    End Try
End Sub
'****
Private Sub ASyori()
    Try
        処理
    Catch ex As Exception
        MsgBox("エラー")
    End Try
End Sub


と書いた場合ASyoriで Catch ex As Exception
を書いている為ASyoriでエラーが起こった場合
エラーの記述がダブります。


 ダブるから、何ですか?ASyori で握りつぶしているので、Form_Load の catch ブロックにはいることはありません。なので、ダブってはいません。
コードが複数あるということを言いたい?だったら 2008-02-29 14:32 の indigo-xさんの通りです。

 VB6.0 からのマイグレーションであると言うことはわかりました。でも、何をするために、何を書いているのか、わかりません。そこの所をはっきりさせてくれないと、あなたにとっての最適解は出せません。
つまり、INIファイルREAD処理や、ASyori で、どんな例外的状況が発生し得ると考えるのか。
あるいは、例外を受けない方が、統一されたメッセージダイアログが表示され、ユーザに優しいかもしれません。


 まず、「On Error 〜 の代わりとしての例外処理」という考え方を捨ててください。
じゃないな。
やるべきことをやってないことをうまい具合にごまかすために On Error 〜 や例外処理を使うのは、やめてください。まずは、やるべきことをリストアップし、ひとつずつ確実にこなすべきです。

 今、苦労しておくべきです。苦労を先送りすると、今しなければならない苦労の数倍にふくれあがりますよ。
ugaya
会議室デビュー日: 2006/08/03
投稿数: 18
投稿日時: 2008-03-05 04:18
エラー処理として全て一緒くたにしてしますといろいろと弊害があると思います。

・業務フロー上想定外のエラー
・業務フロー上想定されているエラー

エラーを二つにわけます。

indigo-xさんが指摘されているように、業務フロー上想定外のエラーについては処理の用のイベントがWindowsアプリにしろWebアプリにしろ.netには存在します。この場合はどこもTry〜Ctachで囲む必要はありません。コード全体をTry〜Catchで囲っているようなものなのですから。
そのイベントハンドラで
「不明なエラー」
系のメッセージを表示させれば済むことです。
画面より下のレイヤでは意識する必要はありませんよね。何せ原因不明のエラーなのですから。

「それじゃどこで例外が発生したのかわからないじゃないか!」

ってたまにjavaなり.netなりの経験のない設計者から聞くことがありますが、
例外のスタックトレースを記録しておけば場所の特定は可能です。
(ちなみにこういう人たちは同じエラーでも場所の特定のためにメッセージのIDを変えてくれるという実に迷惑なことをしてくれたりもします。構造化例外の利点が無駄。)

業務フロー上想定されているエラーは業務エラーです。
もし例外が発生した場合は画面以下のレイヤではcatch後普通戻り値で上のレイヤに通知します。
(INIファイルを読み込もうとしたらない、とか)
画面のレイヤで例外が発生するよう業務エラーはあまりないと思います。
ただ業務エラーが例外を伴う場合は限られています。

こういう処理の仕方をマイクロソフトは推奨しているという認識です。

なんにせよ、メソッド呼び出しの階層構造のあちこちがTry〜Catchを行うような設計・実装は保守性の面であまりにもデメリットが大きいと思います。そうならないためにも異常系処理には指針が上のように示されています。

1ユースケースのメソッド呼び出しの階層を日本語で書いてみるのをお勧めします。
1ユースケースを日本語適当コード化なんかで書いてみればTry〜Catchが階層構造になるようなことは滅多にならないと思いますよ。

[ メッセージ編集済み 編集者: ugaya 編集日時 2008-03-05 04:18 ]
LANVIN
大ベテラン
会議室デビュー日: 2007/03/12
投稿数: 211
投稿日時: 2008-03-06 10:03
多くのみなさんありがとうございます。

ugayaさんお
「それじゃどこで例外が発生したのかわからないじゃないか!」
についてもう少し教えて頂きたいのですが・・

コード:----------------------------

Private Sub Form_Load
Try
Call INIファイルREAD処理
Call ASyori
Catch ex As Exception
MsgBox("エラー" & "Form_Load")
End Try
End Sub
'****
Private Sub ASyori()
Try
DataSyutoku '***データ取得処理(DLLを使用)
Catch ex As Exception
MsgBox("エラー" & ASyori
End Try
End Sub
'****
データ取得処理のDLLのプログラム
Public Function DataSyutoku ()
Try
処理
Catch ex As Exception
Throw
End Try
End Fuction
-----------------------------------

としましたところ(どこでエラーが発生したか解るように"Form_Load""ASyori"を表示するようにしました)
DataSyutoku でエラーが発生しても"ASyori"で表示します。

実際はDLLの中の処理の部分でエラーが発生したのですから
呼び出し元ではDLLの部分でエラーが発生したことが解るようにしたいのですが・・・

皆さんならどのようにされますか?

宜しくお願いします。
indigo-x
大ベテラン
会議室デビュー日: 2008/02/21
投稿数: 207
お住まい・勤務地: 太陽の塔近く
投稿日時: 2008-03-06 10:24
標準的なアプローチはApplicationException辺りを継承して

識別する例外を作ります。(引数も作ればさらに詳細も入れれます)
ugaya
会議室デビュー日: 2006/08/03
投稿数: 18
投稿日時: 2008-03-06 12:03
ExceptionのStackTraceプロパティでメソッド呼び出しの階層構造を取得することができます。

例えばこのコードで発生する例外をすべてシステムエラーとして処理してみます。


コード:
Public Class MainForm
	Private Sub Form_Load() 
		
		'集約イベントハンドラを定義します
		AddHandler Application.ThreadException, AddressOf Application_ThreadException
		
		Call INIファイルREAD処理 
		Call ASyori 
	End Sub 

	Private Sub ASyori() 
		DataSyutoku '***データ取得処理(DLLを使用)  
	End Sub 

	Public Sub Application_ThreadException(ByVal sender As Object, _
         ByVal e As System.Threading.ThreadExceptionEventArgs)
		
		'ユーザーにはこれで十分だと思います
		MessageBox.Show("不明なエラー")

		'障害解析用ログメソッド呼び出し		
		ログメソッド(e.ex.ToString)
    	End Sub
End Class
 
Public Class 別DLL
	'データ取得処理のDLLのプログラム
	Public Function DataSyutoku () 
		処理 
	End Fuction
End Class



例えばこの状態でDataSyutokuメソッドで例外が発生すれば、
ログには以下のような感じででます。

引用:

なんとかExecption:なんとかエラーが発生しました
Source="アプリケーション名"
StackTrace:
場所 別DLL.DataSyutoku()
場所 MainForm.Asyori()
場所 MainForm.Form_Load()
.
.
.



こんな感じで、メソッド呼び出しの階層が下から上に向かって表示されるので、各々Try〜Catchをしなければ例外の発生した場所がわからないということはありません。
LANVIN
大ベテラン
会議室デビュー日: 2007/03/12
投稿数: 211
投稿日時: 2008-03-06 17:11
返答ありがとうございます。

Public Class 別DLL
'データ取得処理のDLLのプログラム
Public Function DataSyutoku ()
Try
処理
       この中でもTryを書いています    
Catch ex1 As SqlClient.SqlException
Throw
End Try
End Fuction
End Class

ugayaさんの通り修正してみました。
すると
上記のThrowでとまります。

全てのTry をなくすのでしょうか?

それとログメソッドは

ログファイルに書き出すということですか?


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