当前位置:  开发笔记 > 编程语言 > 正文

Try/catch似乎没有效果

如何解决《Try/catch似乎没有效果》经验,为你挑选了4个好方法。



1> Steven Muraw..:

尝试运行远程WMI查询时,我能够复制您的结果.抛出的异常不是由Try/Catch捕获的,Trap也不会捕获它,因为它不是"终止错误".在PowerShell中,存在终止错误和非终止错误.似乎Try/Catch/Finally和Trap仅适用于终止错误.

它被记录到$ error自动变量,您可以通过查看$来测试这些类型的非终止错误?自动变量,它会让你知道最后一次操作是成功($ true)还是失败($ false).

从生成的错误的外观,似乎返回错误,而不是包含在可捕获的异常中.下面是生成的错误的痕迹.

PS C:\scripts\PowerShell> Trace-Command -Name errorrecord  -Expression {Get-WmiObject win32_bios -ComputerName HostThatIsNotThere}  -PSHost
DEBUG: InternalCommand Information: 0 :  Constructor Enter Ctor
Microsoft.PowerShell.Commands.GetWmiObjectCommand: 25857563
DEBUG: InternalCommand Information: 0 :  Constructor Leave Ctor
Microsoft.PowerShell.Commands.GetWmiObjectCommand: 25857563
DEBUG: ErrorRecord Information: 0 :  Constructor Enter Ctor
System.Management.Automation.ErrorRecord: 19621801 exception =
System.Runtime.InteropServices.COMException (0x800706BA): The RPC
server is unavailable. (Exception from HRESULT: 0x800706BA)
   at
System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   at System.Management.ManagementScope.InitializeGuts(Object o)
   at System.Management.ManagementScope.Initialize()
   at System.Management.ManagementObjectSearcher.Initialize()
   at System.Management.ManagementObjectSearcher.Get()
   at Microsoft.PowerShell.Commands.GetWmiObjectCommand.BeginProcessing()
errorId = GetWMICOMException errorCategory = InvalidOperation
targetObject =
DEBUG: ErrorRecord Information: 0 :  Constructor Leave Ctor
System.Management.Automation.ErrorRecord: 19621801

解决代码的方法可能是:

try
{
    $colItems = get-wmiobject -class "Win32_PhysicalMemory" -namespace "root\CIMV2" -computername $strComputerName -Credential $credentials
    if ($?)
    {
      foreach ($objItem in $colItems) 
      {
          write-host "Bank Label: " $objItem.BankLabel
          write-host "Capacity: " ($objItem.Capacity / 1024 / 1024)
          write-host "Caption: " $objItem.Caption
          write-host "Creation Class Name: " $objItem.CreationClassName      
          write-host
      }
    }
    else
    {
       throw $error[0].Exception
    }


您可以通过使用以下命令来抛出非终止错误:-ErrorAction"Stop"(或简称-EA"Stop")
@JasonMArcher - 对不对!将$ ErrorActionPreference设置为'Stop'也可以,但会产生全局效果.
在执行关键行之前,不要忘记清除错误集合.`$ error.Clear()`
@Steven Murawski-除非您在FInally块中取消设置。

2> Jon Donnelly..:

如果您希望try/catch适用于所有错误(而不仅仅是终止错误),您可以通过设置ErrorActionPreference手动使所有错误终止.

try {

   $ErrorActionPreference = "Stop"; #Make all errors terminating
   get-item filethatdoesntexist; # normally non-terminating
   write-host "You won't hit me";  
} catch{
   Write-Host "Caught the exception";
   Write-Host $Error[0].Exception;
}finally{
   $ErrorActionPreference = "Continue"; #Reset the error action pref to default
}

或者......您可以创建自己的trycatch函数来接受脚本块,这样您的try catch调用就不会像kludge一样.我有我的返回true/false,以防我需要检查是否有错误...但它不必.此外,异常日志记录是可选的,并且可以在catch中处理,但我发现自己总是在catch块中调用日志记录函数,所以我将它添加到try catch函数中.

function log([System.String] $text){write-host $text;}

function logException{
    log "Logging current exception.";
    log $Error[0].Exception;
}


function mytrycatch ([System.Management.Automation.ScriptBlock] $try,
                    [System.Management.Automation.ScriptBlock] $catch,
                    [System.Management.Automation.ScriptBlock]  $finally = $({})){



# Make all errors terminating exceptions.
    $ErrorActionPreference = "Stop";

    # Set the trap
    trap [System.Exception]{
        # Log the exception.
        logException;

        # Execute the catch statement
        & $catch;

        # Execute the finally statement
        & $finally

        # There was an exception, return false
        return $false;
    }

    # Execute the scriptblock
    & $try;

    # Execute the finally statement
    & $finally

    # The following statement was hit.. so there were no errors with the scriptblock
    return $true;
}


#execute your own try catch
mytrycatch {
        gi filethatdoesnotexist; #normally non-terminating
        write-host "You won't hit me."
    } {
        Write-Host "Caught the exception";
    }



3> 小智..:

也可以在单个cmdlet上设置错误操作首选项,而不仅仅是整个脚本.这是使用所有cmdlet上都可用的参数ErrorAction(alisa EA)完成的.

try 
{
 Write-Host $ErrorActionPreference; #Check setting for ErrorAction - the default is normally Continue
 get-item filethatdoesntexist; # Normally generates non-terminating exception so not caught
 write-host "You will hit me as exception from line above is non-terminating";  
 get-item filethatdoesntexist -ErrorAction Stop; #Now ErrorAction parameter with value Stop causes exception to be caught 
 write-host "you won't reach me as exception is now caught";
}
catch
{
 Write-Host "Caught the exception";
 Write-Host $Error[0].Exception;
}



4> 小智..:

这是我的解决方案。当Set-Location失败时,它将引发一个非终止错误,catch块不会看到该错误。添加-ErrorAction Stop是解决此问题的最简单方法。

try {
    Set-Location "$YourPath" -ErrorAction Stop;
} catch {
    Write-Host "Exception has been caught";
}

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有