【问题标题】:throwing more than one custom exception in powershell在 powershell 中抛出多个自定义异常
【发布时间】:2022-05-20 05:02:24
【问题描述】:

我有一种情况,我必须在我的 powershell 脚本的 try 块中抛出多个自定义异常,如下所示

try {
    if (!$condition1) {
        throw [MyCustomException1] "Error1"
    }
    if (!$condition2) {
        throw [MyCustomException2] "Error2"
    }
}catch [MyCustomException1] {
    #do some business logic
}catch [MyCustomException2] {
    #do some other business logic
}catch{
    #do something else
}

有没有办法在powershell中做到这一点,而无需编写.net类MyCustomException1MyCustomException2。我不必在课堂上存储任何信息,但我只需要一种方法来区分异常。 我可以这样做,但我只是想知道是否更清洁。

try {
    if (!$condition1) {
        throw "Error1"
    }
    if (!$condition2) {
        throw "Error2"
    }
}catch {
    if($_.tostring() -eq "Error1"){
        Write-Host "first exception"
    }elseif($_.tostring() -eq "Error2"){
        Write-Host "Second exception"
    }else {
        Write-Host "third exception"
    }
}

注意:我已经检查了下面的堆栈溢出问题:powershell-creating-a-custom-exceptionpowershell-2-0-try-catch-how-to-access-the-exceptionpowershell-creating-and-throwing-new-exception 但它没有回答我的问题。

【问题讨论】:

    标签: powershell exception-handling


    【解决方案1】:

    感谢@BenH 和@TheIncorrigible1 关于创建类和异常的建议。如果其他人也在寻找相同的东西,下面是一个示例代码。

    class MyEXCP1: System.Exception{
        $Emessage
        MyEXCP1([string]$msg){
            $this.Emessage=$msg
        }
    }
    class MyEXCP2: System.Exception{
        $Emessage
        MyEXCP2([string]$msg){
            $this.Emessage=$msg
        }
    }
    $var=2
    try{
        if($var -eq 1){
            throw [MyEXCP1]"Exception 1"
        }
        if($var -eq 2){
            throw [MyEXCP2]"Exception 2"
        }
    }catch [MyEXCP1]{
        Write-Output "Exception 1 thrown"
    }catch [MyEXCP2]{
        Write-Output "Exception 2 thrown"
    }
    

    【讨论】:

      【解决方案2】:

      您可以查看$error 变量上的FullyQualifiedErrorID 属性以从throw 语句中获取字符串。

      try {throw "b"}
      catch {
          if ($error[0].FullyQualifiedErrorID -eq "a") {'You found error "a"'}
          if ($error[0].FullyQualifiedErrorID -eq "b") {'You found error "b"'}
      }
      

      但看起来您并不是真的想Try Catch 而是要犯非终止错误。您可以使用Write-Error 来执行此操作。

      if (!$condition1) {
          Write-Error "Error1"
      }
      if (!$condition2) {
          Write-Error "Error2"
      }
      

      【讨论】:

      • 我想在不同的 catch 块中捕获错误,而不是在一个 catch 块中然后放置 if 条件。我需要在 catch 块中执行一些业务逻辑。为了让问题简单,我只是把 write-host 语句
      • @Pramod 每种错误类型都有一个catch,但您声明不想创建错误类型。
      • 是的,我只是想知道是否有任何方法可以在不为 MyCustomException1MyCustomException2 创建 .net 类的情况下为每个错误类型获取一个 catch 块。
      • @pramod 有很多内置类型。 [System.Management.Automation.CommandNotFoundException], [System.SystemException],[System.Net.WebException],[System.IO.IOException] 如果您不想使用 pre-制作类型然后使用您需要创建类型...
      • @Pramod 这个question 也可能对如何在 PowerShell 中创建类有所帮助
      【解决方案3】:

      您可以利用$PSCmdlet.ThrowTerminatingError 并定义您自己的ErrorRecord 对象。

      这里是 another useful article,关于 PowerShell 中的错误处理。

      关于自定义类的问题,您也可以在 PSv5+ 中使用自己的类


      阅读完您的 cmets 后,您可以通过以下方式找出要处理的错误

      Catch { "[$($_.Exception.GetType().FullName)]" }
      

      这为您提供了正在抛出的错误类别。搭配:

      Catch { $_.Exception.Message }
      

      您还可以查看系统报告的内容。

      【讨论】:

        【解决方案4】:

        我只是想找到一些真正基本的错误处理方法,然后我想出了这个:

        try {
            $a = 1
            if($a-eq1) { throw "OneException" }
            if($a-eq2) { throw "TwoException" }
        } catch {
            switch ($error[0]){
                "OneException" { echo "one" }
                "TwoException" { echo "two" }
                default { echo $_.Exception }
            }
        }
        

        不花哨,但实用:)

        【讨论】:

        • 这与问题提出的相同,只是您将if...elseif... 简化为switch。通过这样做,您将失去为每个 Exception 类型设置 catch 块的能力。
        • 我同意兰斯的观点。这是 - 对我来说 - 一个糟糕的编程示例,并且没有使用提供的语言功能。
        猜你喜欢
        • 2011-10-06
        • 2012-10-28
        • 2011-05-30
        • 1970-01-01
        • 1970-01-01
        • 2021-11-22
        • 2011-04-14
        • 2015-04-25
        相关资源
        最近更新 更多