使用默认消息扩展 Powershell 中的异常

Extending Exceptions in Powershell with default message

我一直在努力思考如何在 PowerShell 中扩展异常。我在 class 的第一次通过看起来像这样...

class CustomException : Exception {
    CustomException () {
    }
    CustomException ([String] $message) : base ($message) {
    }
}

并且按预期使用,第一种方法生成类型名称,第二种方法生成提供的消息...

try {
    throw [CustomException]
} catch {
    "$($_.Exception.Message)"
}
try {
    throw [CustomException] 'Another message'
} catch {
    "$($_.Exception.Message)"
}

不过,我真的很想有一个默认消息,所以我可以在很多地方使用第一个例子,但如果我想修改消息,我可以在 class 中一次性完成。或者甚至可能在某个时候将消息本地化。 This thread 似乎暗示它在 C# 中是可能的,尤其是最后两篇文章。所以,以最后一个例子为例...

public class MyException : Exception
{
    public MyException () : base("This is my Custom Exception Message")
    {
    }
}

我以为我可以在 Powershell 中做同样的事情,就像这样...

CustomException () : base ('Default message') {
}

但在不提供消息时我仍然得到类型名称。这让我开始思考,我尝试了...

try {
    throw [System.IO.FileNotFoundException]
} catch {
    "$($_.Exception.Message)"
}

并且 ALSO 不提供默认消息,仅提供 class 名称。那么,C# 代码是否没有按照我的想法执行?或者这只是 Powershell 中的行为差异?还是我做错了什么?

你想要的完美支持,但你需要抛一个实例异常!

throw的语法基本上是:

throw [Throwable]

其中 Throwable 是 ErrorRecord、Exception 或字符串(基本上是简单的错误消息)。

当您抛出类型字面量 [CustomException] 时,PowerShell 将该表达式转换为 [string],这就是为什么您只在 catch 块中看到类型名称的原因。

正确抛出异常实例需要调用构造函数:

class CustomException : Exception
{
  CustomException() : base("default CustomException message goes here")
  {
  }
}

try {
    throw [CustomException]::new()    # <-- don't forget to call the constructor
} catch {
    "$_"
}