AppDomain.CurrentDomain.UnhandledException在System.CommandLine中无法捕获异常怎么办?
问题原因
System.CommandLine 内部会默认捕获命令执行过程中抛出的异常,将其转换为命令执行失败的结果(设置对应退出码),不会让异常直接传播到 AppDomain 层面,因此你的 UnhandledExceptionTrapper 无法捕获到这些异常。
解决方案
方案一:执行后检查结果并重新抛出异常
调用 InvokeAsync 后获取执行结果,若存在异常则主动抛出,让 AppDomain.CurrentDomain.UnhandledException 事件捕获:
using System.CommandLine; AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper; var testCommand = new Command("test"); testCommand.SetAction(args => { int x = 0; int y = 15 / x; }); RootCommand rootCommand = new RootCommand { testCommand }; var invocationResult = await rootCommand.Parse(args).InvokeAsync(); // 检查执行结果,有异常则重新抛出 if (invocationResult.Exception != null) { throw invocationResult.Exception; } static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine("Inside UnhandledExceptionTrapper"); Console.WriteLine(e.ExceptionObject.ToString()); System.Environment.Exit(1); }
方案二:使用中间件传递异常
给根命令添加中间件,绕开 System.CommandLine 的默认异常捕获逻辑,让异常直接冒泡到 AppDomain 层面:
using System.CommandLine; AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper; var testCommand = new Command("test"); testCommand.SetAction(args => { int x = 0; int y = 15 / x; }); RootCommand rootCommand = new RootCommand { testCommand }; // 添加中间件,将执行产生的异常重新抛出 rootCommand.AddMiddleware(async (context, next) => { await next(context); if (context.Exception != null) { throw context.Exception; } }); await rootCommand.Parse(args).InvokeAsync(); static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine("Inside UnhandledExceptionTrapper"); Console.WriteLine(e.ExceptionObject.ToString()); System.Environment.Exit(1); }
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

