C#でプログラムを書いているとき、エラーが発生したらとりあえずthrowしますよね?
その例外は、どこかでcatchして、メッセージボックスなりエラーログなりで出力しなくてはいけません。
忘れると、例外発生時に情報無しで落ちてしまって、情報収集がしにくくなります。
しかし、開発中にきちんとしたエラー処理を書くのも面倒なので、とりあえず捕捉しなかったエラーは全部1カ所で処理したいものです。
単純にApplication.Run()をtry-catchで囲っても、正しく処理できません。
この場合は、ApplicationのThreadException
と ThreadのUnhandledException
を使います。
下記のサンプルコードのようにすると、catchされなかった例外はメッセージボックスを表示し、同じディレクトリのerror.txtに詳細が記録されます。
開発中でエラーポリシーも詳細が決まっていないとき、とりあえずこのような処理を入れておくと、デバッグモード以外で起動してもエラー詳細が見られて便利です。
//サンプルコード
[STAThread]
static void Main()
{
//エラーハンドラを登録
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
if (ex != null)
{
ShowError(ex, "UnhandledException");
}
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
ShowError(e.Exception, "ThreadException");
}
static void ShowError(Exception ex, string title)
{
MessageBox.Show("プログラム中で補足されなかったエラーが発生しました。詳細はエラーログをごらん下さい。", title);
StreamWriter stream = new StreamWriter("error.txt", true);
stream.WriteLine("[" + title + "]");
stream.WriteLine("[message]\r\n" + ex.Message);
stream.WriteLine("[source]\r\n" + ex.Source);
stream.WriteLine("[stacktrace]\r\n" + ex.StackTrace);
stream.WriteLine();
stream.Close();
}