このドキュメントの内容
例外のスタックトレースを読みやすく整形してくれるライブラリ Ben.Demystifier
の紹介です。
近年 C# の機能は大きく進化し、async, LINQ, イテレータなどコーディングスタイルも変わってきています。それに伴い、スタックトレースが人間には読みづらい内容になることも多いです。そのような場面で便利なライブラリです。
実行サンプル
ソースコード
Exception に対する拡張メソッド Demystify を呼び出し、整形されたスタックトレースを出力します。
using System.Diagnostics;
private async void button1_Click(object sender, EventArgs e)
{
try
{
await RunAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("----- StackTrace -----");
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
System.Diagnostics.Debug.WriteLine("----- Demystify -----");
System.Diagnostics.Debug.WriteLine(ex.Demystify());
}
}
private Task RunAsync()
{
// ローカル関数を介して処理を実行する
Task RunTasks<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3)
{
// 例外をキャッチしてスローしなおす
try
{
return Task.WhenAll(Execute001Async(arg1), Execute002Async(arg2, arg3));
}
catch (Exception ex)
{
throw new Exception("処理中に例外が発生しました。", ex);
}
}
return RunTasks("abc", 1, DateTime.Now);
}
private Task Execute001Async<T>(T arg)
{
return Task.CompletedTask;
}
private Task Execute002Async<T1, T2>(T1 arg1, T2 arg2)
{
int[] values = new[] { 1, 2, 3, 0 };
// ここでゼロ除算例外がスローされる
foreach (var result in values.Select(x => 10 / x))
{
}
return Task.CompletedTask;
}
出力結果
Exception.StackTrace
場所 WindowsFormsApp1.Form1.<RunAsync>g__RunTasks|2_0[T1,T2,T3](T1 arg1, T2 arg2, T3 arg3) 場所 E:\Source\Work\DemystifierSample\WindowsFormsApp1\Form1.cs:行 47
場所 WindowsFormsApp1.Form1.RunAsync() 場所 E:\Source\Work\DemystifierSample\WindowsFormsApp1\Form1.cs:行 51
場所 WindowsFormsApp1.Form1.<button1_Click>d__1.MoveNext() 場所 E:\Source\Work\DemystifierSample\WindowsFormsApp1\Form1.cs:行 25
- ローカル関数や LINQ 式がリーダブルな形式で展開されています。
- 内部例外が格納されている場合、内部例外も出力されています。
Exception.Demystify()
System.Exception: 処理中に例外が発生しました。 ---> System.DivideByZeroException: 0 で除算しようとしました。
at Task WindowsFormsApp1.Form1.Execute002Async<T1, T2>(T1 arg1, T2 arg2)+(int x) => { } in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 64
at bool System.Linq.Enumerable+WhereSelectArrayIterator<TSource, TResult>.MoveNext()
at Task WindowsFormsApp1.Form1.Execute002Async<T1, T2>(T1 arg1, T2 arg2) in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 64
at Task WindowsFormsApp1.Form1.RunAsync()+RunTasks(T1 arg1, T2 arg2, T3 arg3) in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 43
--- 内部例外スタック トレースの終わり ---
at Task WindowsFormsApp1.Form1.RunAsync()+RunTasks(T1 arg1, T2 arg2, T3 arg3) in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 47
at Task WindowsFormsApp1.Form1.RunAsync() in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 51
at async void WindowsFormsApp1.Form1.button1_Click(object sender, EventArgs e) in E:/Source/Work/DemystifierSample/WindowsFormsApp1/Form1.cs:line 25