当 Main 抛出异常时,Environment.ExitCode 不受尊重。如何返回非零退出代码以及抛出异常?

Posted

技术标签:

【中文标题】当 Main 抛出异常时,Environment.ExitCode 不受尊重。如何返回非零退出代码以及抛出异常?【英文标题】:Environment.ExitCode not respected when Main throws exception. How to return nonzero exitcode as well as throwing exception? 【发布时间】:2020-04-28 15:19:50 【问题描述】:
// Net core 3.1 Console application
class Program

   public static void Main()
   
      Environment.ExitCode = 1;
      throw new Exception("boom");
   

以上代码导致退出代码0!

我希望它是1

https://docs.microsoft.com/en-us/dotnet/api/system.environment.exitcode?view=netcore-3.1 表示“获取或设置进程的退出代码。”。此外,“如果 Main 方法返回 void,您可以使用该属性设置将返回给调用环境的退出代码。”

如果我删除异常抛出,退出代码是1,正如预期的那样。

我认为Environment.ExitCode 的真正意义在于指定将使用的退出代码,除非程序达到以其他方式设置的点。

如何确保退出代码不为零。虽然仍然不需要捕获所有异常?我希望异常与非零退出代码一起实际抛出,因为环境可以使用它来显示相关的错误消息。

我真的需要在捕获任何和所有异常(例如为AppDomain.CurrentDomain.UnhandledException 添加处理程序)还是能够返回我选择的退出代码之间做出选择?

【问题讨论】:

UnhandledException 有什么不好? @cassandrad 如果我执行AppDomain.CurrentDomain.UnhandledException += (s, e) => Environment.Exit(1); 之类的操作,那么基本上我处理了异常并且环境(例如 kubernetes)不会看到异常消息。另外我想知道Environment.ExitCode=1 有什么意义,如果我必须使用Environment.Exit(1) 来确保我返回预期的退出代码。 kubernates 将如何处理异常消息? Environment.Exit(1) 需要立即停止进程,以防万一有可能损坏数据或其他严重错误,而 return 语句和 Environment.ExitCode 允许应用程序继续执行,但是两者可以返回不同的代码。所以Environment.Exit(1) 的概念意义不同于其他两个。 【参考方案1】:

我也在这里https://github.com/dotnet/runtime/issues/35599 提出了一个问题。有人指出,退出代码0 似乎是视觉工作室特有的东西。它在正常环境中输出非零值。但是,自定义的Environment.ExitCode 仍然没有在异常情况下使用。异常处理是特定于操作系统的 - 重要的是确实应该在 prod 中的异常上返回非零代码。 Environment.ExitCode 的行为是故意不用于异常。

【讨论】:

为我修好了!

以上是关于当 Main 抛出异常时,Environment.ExitCode 不受尊重。如何返回非零退出代码以及抛出异常?的主要内容,如果未能解决你的问题,请参考以下文章

当 string.length() 为 0 时抛出异常

处理 QPluginLoader::load() 抛出的异常

Boost::Asio - 抛出 get_io_service 异常

抛出异常后不执行 Catch 块调试语句?

在 Lambda 表达式中从 main() 抛出 IOException [重复]

为啥当参数为null时,postgres会抛出异常?