about_Error_Handling

Kısa açıklama

PowerShell'deki hata türlerini ve bunları işleme mekanizmalarını açıklar.

Uzun açıklama

PowerShell üç hata kategorisini ayırt eder:

  • Sonlandırılmayan hatalar
  • Deyim sonlandırma hataları
  • Betik sonlandırma hataları

Her kategori farklı varsayılan davranışa sahip olduğundan ve farklı işleme teknikleri gerektirdiğinden, bu ayrımı anlamak güvenilir betikler ve modüller yazmak için gereklidir.

Ayrıca, dış (yerel) programlar, PowerShell'in kendi hata sisteminden ayrı olarak izlediği çıkış kodları aracılığıyla hata bildirmektedir.

Hata türleri

Sonlandırılmayan hatalar

Sonlandırılmayan bir hata bir sorun bildirir ancak işlem hattını durdurmaz. Komutu sonraki giriş nesnelerini işlemeye devam eder. Sonlandırılmayan hatalar şu şekilde oluşturulur:

  • cmdlet'i Write-Error
  • $PSCmdlet.WriteError() Gelişmiş işlevlerde yöntemi
  • Tek tek giriş nesnelerinde kurtarılabilir hatalarla karşılaşan cmdlet'ler

PowerShell varsayılan olarak hata iletisini görüntüler ve yürütmeye devam eder.

# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
    Get-Content $_ -ErrorAction Continue
}

Bu örnekte, Get-Content için noSuchFile.txt sonlandırılmayan bir hata bildirir ve işlemeye file3.txtdevam eder.

Sonlandırılmayan hatalar tetiklenmezcatch veya trap varsayılan olarak tetiklenmez.

Deyim sonlandırma hataları

Deyim sonlandırma hatası geçerli deyimin (işlem hattı) çalışmasını durdurur, ancak yürütme betiğin sonraki deyiminde devam eder. Deyim sonlandırma hataları şu şekilde oluşturulur:

  • $PSCmdlet.ThrowTerminatingError() Gelişmiş işlevlerde ve derlenmiş cmdlet'lerde yöntemi
  • (Var olmayan bir komutu çağırma) ve CommandNotFoundException (geçersiz parametre bağımsız değişkenleri) gibi ParameterBindingException altyapı hataları
  • Gibi özel durumlar oluşturan .NET yöntemi çağrıları [int]::Parse('abc')
# Statement-terminating error: Get-Item fails, but the next statement runs
Get-Item -Path 'C:\NoSuchFile.txt'
Write-Output 'This still runs'

deyim sonlandırma hataları ve try/catchtarafından trap yakalanabilir.

Uyarı

.ThrowTerminatingError() parametresine -ErrorAction danışmaz (hata ayıklayıcıyı Break giren değer dışında). Ancak, $ErrorActionPreference altyapının deyim düzeyi işleyicisi aracılığıyla deyim sonlandırma hataları için geçerlidir. Örneğin, $ErrorActionPreference = 'SilentlyContinue' betiğin sonraki deyimde devam etmesi için deyim sonlandırma hatasını gizleyebilir. -ErrorAction parametresi bunu yapamaz. Ayrıntılar için bkz . $ErrorActionPreference asimetrisi.

Betik sonlandırma hataları

Betik sonlandırma hatası çağrı yığınının tamamını geri alır. Hata bir try/catch blok veya trap deyim tarafından yakalanmadığı sürece yürütme tamamen durdurulur. Betik sonlandırma hataları şu şekilde oluşturulur:

  • throw anahtar sözcüğü
  • Ayrıştırma hataları (betiğin derlenmesini engelleyen söz dizimi hataları)
  • Gelişmiş olmayan bağlamlarda veya tarafından -ErrorAction Stop$ErrorActionPreference = 'Stop' sonlandırılmayan hatalar. Daha fazla bilgi için bkz. Yükseltme nasıl çalışır?
  • Bazı kritik altyapı hataları
# Script-terminating error: throw unwinds the call stack
function Test-Throw {
    throw 'Critical failure'
    Write-Output 'This never runs'
}

Test-Throw
Write-Output 'This never runs either (unless caught)'

anahtar throw sözcüğü varsayılan olarak bir betik sonlandırma hatası oluşturur. Ancak, $ErrorActionPreference veya olarak ayarlandığında throwSilentlyContinueIgnore. ile -ErrorAction SilentlyContinuegelişmiş bir işlev çağrılırken parametresi scope-local $ErrorActionPreference değerine çevrilir, bu nedenle bu işlevin içinde de gizlenir throw .

Uyarı

ile $ErrorActionPreference = 'Ignore'bile, gizlenen bir throw yine de içinde $Errorbir girdi kaydeder. Ignore değeri yalnızca $Error hatalar için kaydı engeller.

Önemli

Deyimi sonlandırıcı ve betik sonlandırıcı terimleri, hatanın önem derecesini değil etki kapsamını açıklar. Deyim sonlandırma hatası bir deyimi durdurur. Betik sonlandırma hatası, betiğin tamamını ve çağıranlarını durdurur. her ikisi de tarafından try/catchyakalanabilir.

Dış program hataları

Dış (yerel) programlar PowerShell'in hata sistemine doğrudan katılmaz. PowerShell'in otomatik değişkende $LASTEXITCODE depoladığı sıfır olmayan bir çıkış kodu aracılığıyla hata bildirir.

git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
    Write-Error "git failed with exit code $LASTEXITCODE"
}

Varsayılan olarak, yerel bir programdan sıfır olmayan çıkış kodu:

  • Ayarlar $? : $false
  • içinde oluşturmazErrorRecord$Error
  • Tetiklemezcatch veyatrap

PowerShell 7.3, 7.4'te kararlı bir özellik haline gelen deneysel tercih değişkenini $PSNativeCommandUseErrorActionPreferenceekledi. Bu değişkeni olarak $trueayarladığınızda, sıfır olmayan bir çıkış kodunun, iletisinde belirli bir çıkış kodunu (a) bildiren sonlandırılmayan bir NativeCommandExitExceptionhata yayması neden olur. Bu hataya saygı $ErrorActionPreferencegösterir, Stop bu nedenle hatanın ile yakalanabilecek try/catchbir betik sonlandırıcı hataya yükseltilmesine neden olur.

Hata durumu değişkenleri

PowerShell, geçerli hata durumunu yansıtan birkaç otomatik değişken tutar.

$?

Son işlemin başarılı olup olmadığını ve $true herhangi bir hata (sonlandırıcı veya sonlandırıcı olmayan) üretip üretmediğini içerir$false. Yerel komutlar için çıkış $? koduna göre ayarlanır: $true çıkış kodu 0için, $false aksi takdirde.

Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$?  # False

$Error

ArrayList dizininde en son hatayla birlikte en son hata kayıtlarını depolayan bir .0 Listede en fazla $MaximumErrorCount girdi vardır (varsayılan 256).

Tüm sonlandırıcı hatalar öğesine $Erroreklenir. Sonlandırıcı hatalar için, Ignore görüntülemeyi bastırır ancak yine de $Erroriçinde hata kaydeder. Sonlandırıcı olmayan tüm hatalar, hem görüntülemeyi hem de kaydı engelleyen sonlandırma olmayan hatalarda kullanılmadığı sürece $Error öğesine eklenir-ErrorAction Ignore.

$LASTEXITCODE

Çalıştıran son yerel programın çıkış kodunu içerir. Değeri geleneksel olarak başarıyı 0 gösterir. Sıfır olmayan herhangi bir değer hataya işaret eder. Bu değişken PowerShell cmdlet hatalardan etkilenmez.

Denetim hatası davranışı

Ortak -ErrorAction parametre

Ortak -ErrorAction parametre, tek bir komut için geçersiz kılar $ErrorActionPreference . PowerShell'in bu komuttan sonlandırıcı olmayan hatalara nasıl yanıt vereceğini denetler.

Değer Davranış
Continue Hatayı görüntüleme ve devam et (varsayılan)
SilentlyContinue Ekranı gizle, öğesine $Errorekle, devam et
Ignore Ekranı gösterme ve ekleme $Error
Stop Sonlandırıcı bir hataya yükseltme (bkz. Yükseltme nasıl çalışır)
Inquire Kullanıcıdan bir karar iste
Break Hata ayıklayıcıyı girin

-ErrorAction tarafından $PSCmdlet.ThrowTerminatingError()oluşturulan hataların davranışını değiştirmez. Bu hatalar, çağıranın tercihi ne olursa olsun her zaman deyim sonlandırıcıdır.

Değişken $ErrorActionPreference

Tercih $ErrorActionPreference değişkeni geçerli kapsam ve alt kapsamlardaki tüm komutlar için geçerlidir. ile aynı değerleri kabul eder -ErrorAction.

$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws'   # Generates ActionPreferenceStopException

-ErrorAction Bir komutta belirtildiğinde, bu komut için öncelikli $ErrorActionPreference olur.

Yükseltme nasıl çalışır?

Veya -ErrorAction Stop etkin olduğunda$ErrorActionPreference = 'Stop', PowerShell aşağıdaki mekanizmayı kullanarak sonlandırılmayan hataları sonlandırma hatalarına dönüştürür:

  1. Bir cmdlet, sonlandırılmayan bir hata yaymak için dahili olarak çağırır WriteError() .
  2. Altyapı, komutu için geçerli ErrorAction tercihi denetler.
  3. Tercih olduğundan Stop, altyapı özgün hata kaydını sarmalayan bir ActionPreferenceStopException oluşturur.
  4. tarafından catchyakalanırsa, özgün hata bilgilerine üzerinden $_.Exception.ErrorRecorderişilebilir.

Yükseltilen hatanın kapsamı bağlama bağlıdır:

  • Gelişmiş olmayan betiklerde, işlevlerde veya betik bloklarında, ayar $ErrorActionPreference = 'Stop'bir betik sonlandırma hatasına ilerler. Hata, çağrı yığınını yukarı yayılım.
  • Gelişmiş işlevlerde ve betik bloklarında (ile olanlar[CmdletBinding()]) hata deyimini sonlandırıcı olarak kalır. Yürütme, çağrıdan sonraki deyimde devam eder.
  • -ErrorAction Stop Gelişmiş bir işleve geçiş, içinde ayar $ErrorActionPreference = 'Stop' yapmakla aynı etkiye sahiptir çünkü -ErrorAction kapsam yerel $ErrorActionPreference değerine çevrilir.

İlerletme örnekleri

  • GELIŞMIŞ OLMAYAN: betik sonlandırıcı ('after' yazdırılmıyor)

    & {
        param()
        $ErrorActionPreference = 'Stop'
        1/0  # Divide by zero error
    } 2>$null
    'after'
    
  • GELİşMİş: deyim sonlandırıcı ('after' YAZDıRMA YAPAR)

    & {
        [CmdletBinding()]
        param()
        $ErrorActionPreference = 'Stop'
        1/0  # Divide by zero error
    } 2>$null
    'after'
    
  • olmadan -ErrorAction Stop: sonlandırılmayan catch çalışmaz

    try {
        Write-Error 'This is non-terminating'
        Write-Output 'Execution continues'
    } catch {
        Write-Output "Caught: $_"   # Not reached
    }
    
  • ile -ErrorAction Stop: sonlandırıcıya yükseltildi

    try {
        Write-Error 'This becomes terminating' -ErrorAction Stop
    } catch {
        Write-Output "Caught: $_"   # Reached
    }
    

Yükseltilen hatalar özgün özel durum türü tarafından yakalanabilir. Altyapı, temel alınan özel durumu bulmak için unwraps ActionPreferenceStopException :

try {
    Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
    Write-Output "File not found: $($_.Exception.Message)"
}

Asimetri $ErrorActionPreference

-ErrorAction parametresi ve $ErrorActionPreference değişkeni, sonlandırıcı hatalarla farklı davranır. Bu asimetriyi anlamak önemlidir:

  • -ErrorAction yalnızca sonlandırılmayan hataları etkiler. Bir cmdlet çağırdığında $PSCmdlet.ThrowTerminatingError()-ErrorAction parametresi yoksayılır (Breakhata ayıklayıcıya giren dışında). Hata her zaman oluşturulur.

  • $ErrorActionPreference hem sonlandırıcı olmayan hem de deyimi sonlandırıcı hataları etkiler. Altyapının deyim düzeyi hata işleyicisi (parametresini değil) okur $ErrorActionPreference ve değer -ErrorAction veya SilentlyContinueolduğunda deyim sonlandırma hatasını gizleyebilir.Ignore

function Test-Asymmetry {
    [CmdletBinding()]
    param()
    $er = [System.Management.Automation.ErrorRecord]::new(
        [System.InvalidOperationException]::new('test error'),
        'TestError',
        [System.Management.Automation.ErrorCategory]::InvalidOperation,
        $null
    )
    $PSCmdlet.ThrowTerminatingError($er)
}

# -ErrorAction SilentlyContinue does NOT suppress the error:
Test-Asymmetry -ErrorAction SilentlyContinue   # Error is still thrown

# $ErrorActionPreference DOES suppress the error:
$ErrorActionPreference = 'SilentlyContinue'
Test-Asymmetry   # Error is silently suppressed, script continues
$ErrorActionPreference = 'Continue'

Önemli

$ErrorActionPreferenceolarak ayarlanmış SuppressPromptInInterpreterhataları true gizleyemez. Bunlar tercih değişkenine bakılmaksızın her zaman yayılır. Bu tür hata örnekleri şunlardır:

  • ActionPreferenceStopExceptionyükseltmeden -ErrorAction Stop
  • PowerShell sınıf yöntemlerindeki hatalar
  • PipelineStoppedException

Hatalarla başa çıkma

try/catch/finally

Deyim sonlandırma ve betik sonlandırma hatalarını işlemek için kullanın try/catch/finally . Bir try bloğun içinde hata oluştuğunda PowerShell eşleşen catch bir bloğu arar. Bir finally hata oluşup oluşmadığı fark etmeksizin blok her zaman çalışır.

try {
    $result = Get-Content -Path 'data.txt' -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
    Write-Warning 'Data file not found, using defaults.'
    $result = 'default'
}
catch {
    Write-Warning "Unexpected error: $_"
}
finally {
    Write-Verbose 'Cleanup complete.' -Verbose
}

Bir try bloğun içinde altyapı, veya tarafından -ErrorAction Stop yükseltilen veya $ErrorActionPreference = 'Stop' bloğuna yayılması için sonlandırılmayan catch hatalara neden olan bir iç bayrak ayarlar. Bu özel bir durum değil, tasarlanmış bir davranıştır.

Tam söz dizimi ayrıntıları için bkz. about_Try_Catch_Finally.

trap

deyimi, trap kapsam düzeyinde sonlandırma hatalarını işler. Kapsayan kapsamda herhangi bir yerde hata oluştuğunda trap , blok çalışır.

  • Varsayılan (hayır break veya continue): Hata görüntülenir ve yürütme, hataya neden olan deyimden sonraki deyimde devam eder.
  • continue tuzakta: Hata iletisini gizler ve sonraki deyimde devam eder.
  • break tuzakta: Hata üst kapsama yayılır.
trap [System.Management.Automation.CommandNotFoundException] {
    Write-Warning "Command not found: $($_.TargetObject)"
    continue
}

NonsenseCommand   # Trap fires, execution continues
Write-Output 'This runs because the trap used continue'

Söz dizimi ayrıntılarının tamamı için bkz. about_Trap.

İşlevlerde ve betiklerde hataları raporlama

İşlevler ve betikler yazarken, hatanın önem derecesiyle eşleşen hata raporlama mekanizmasını seçin.

Sonlandırılmayan - kullanım Write-Error

İşlev diğer girişleri işlemeye devam edebilirken kullanın Write-Error . Bu, birden çok nesneyi işleyen ve tek tek öğelerde hatalarla karşılaşan işlem hattı işlevleri için uygundur.

function Test-Path-Safe {
    [CmdletBinding()]
    param([Parameter(ValueFromPipeline)][string]$Path)
    process {
        if (-not (Test-Path $Path)) {
            Write-Error "Path not found: $Path"
            return
        }
        $Path
    }
}

Uyarı

Gelişmiş işlevlerde (ile olanlar[CmdletBinding()]), çağıranın kapsamında düzgün şekilde ayarlandığından $PSCmdlet.WriteError() emin olmak için Write-Error yerine $? kullanın$false. Write-Error Cmdlet her zaman doğru ayarlanmadı$?.

Deyim sonlandırıcı - use $PSCmdlet.ThrowTerminatingError()

İşlevin devam edememesi durumunda kullanın $PSCmdlet.ThrowTerminatingError() , ancak çağıranın hatanın nasıl işleneceğini belirlemesi gerekir. Bu, gelişmiş işlevlerde önerilen yaklaşımdır.

function Get-Config {
  [CmdletBinding()]
  param([string]$Path)

  if (-not (Test-Path $Path)) {
    $er = [System.Management.Automation.ErrorRecord]::new(
      [System.IO.FileNotFoundException]::new("Config file not found: $Path"),
      'ConfigNotFound',
      [System.Management.Automation.ErrorCategory]::ObjectNotFound,
      $Path
    )
    $PSCmdlet.ThrowTerminatingError($er)
  }

  Get-Content $Path | ConvertFrom-Json
}

Hata işlevden çıktıktan sonra çağıran bunu varsayılan olarak sonlandırılmayan bir hata olarak ele alır. Çağıran ile -ErrorAction Stopyükseltebilir.

Betik sonlandırma - kullanım throw

Kurtarma mümkün olmadığında ve betiğin tamamı durdurulduğunda kullanın throw .

$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
    ConvertFrom-Json

if (-not $config) {
    throw 'Cannot proceed without a valid configuration file.'
}

Kullanılacak mekanizma

  • Bazılarının başarısız olabileceği birden çok girişi işlerken veya Write-Errorkullanın$PSCmdlet.WriteError().
  • İşlev devamamıyorsa işlevini kullanın $PSCmdlet.ThrowTerminatingError() ve çağıranın nasıl işleneceğini belirlemesine izin verin.
  • Betiğin tamamının hemen durması gerekiyorsa kullanın throw.

Hata türlerinin özeti

Aşağıdaki tablolarda PowerShell'deki farklı hata türlerinin özellikleri ve davranışları özetlenmiştir.

Sonlandırılmayan hata

Sonlandırılmayan hatalar veya Write-Errortarafından $PSCmdlet.WriteError() oluşturulabilir.

Özellik Açıklama
Etki kapsamı İşlem hattı devam ediyor
Yakalanan catch Hayır (yükseltilmediği sürece)
Yakalanan trap Hayır (yükseltilmediği sürece)
öğesine eklendi $Error Evet (sürece Ignore)
Ayarlar $? : $false Evet
Etkilenen -ErrorAction Evet
Etkilenen $ErrorActionPreference Evet

Deyim sonlandırma hatası

Deyim sonlandırma hataları, altyapı hataları, .NET yöntemi özel durumları veya ThrowTerminatingError() gelişmiş bağlamlarda oluşturulabilir-ErrorAction Stop.

Özellik Açıklama
Etki kapsamı Geçerli deyim durdurulur; betik devam ediyor
Yakalanan catch Evet
Yakalanan trap Evet
öğesine eklendi $Error Evet
Ayarlar $? : $false Evet
Etkilenen -ErrorAction Hayır (Break yalnızca)
Etkilenen $ErrorActionPreference Evet (gizlenebilir)

Betik sonlandırma hatası

Betik sonlandırma hataları tarafından throw, hataları ayrıştırarak veya -ErrorAction Stop gelişmiş olmayan bağlamlarda oluşturulabilir.

Özellik Açıklama
Etki kapsamı Çağrı yığını geri sarmalar
Yakalanan catch Evet
Yakalanan trap Evet
öğesine eklendi $Error Evet
Ayarlar $? : $false Evet
Etkilenen -ErrorAction Hayır
Etkilenen $ErrorActionPreference throw: Evet (gizlenebilir)
Etkilenen $ErrorActionPreference İlerletildi: bağlama bağlıdır

Ayrıca bakınız