Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Deskripsi singkat
Menjelaskan jenis kesalahan di PowerShell dan mekanisme untuk menanganinya.
Deskripsi panjang
PowerShell membedakan tiga kategori kesalahan:
- Kesalahan non-penghentian
- Kesalahan penghentian pernyataan
- Kesalahan penghentian skrip
Memahami perbedaan sangat penting untuk menulis skrip dan modul yang andal, karena setiap kategori memiliki perilaku default yang berbeda dan memerlukan teknik penanganan yang berbeda.
Selain itu, program eksternal (asli) melaporkan kegagalan melalui kode keluar, yang dilacak PowerShell secara terpisah dari sistem kesalahannya sendiri.
Jenis kesalahan
Kesalahan non-penghentian
Kesalahan yang tidak mengakhiri melaporkan masalah tetapi tidak menghentikan alur. Perintah melanjutkan pemrosesan objek input berikutnya. Kesalahan yang tidak mengakhiri dihasilkan oleh:
- Cmdlet
Write-Error - Metode
$PSCmdlet.WriteError()dalam fungsi lanjutan - Cmdlet yang mengalami kegagalan yang dapat dipulihkan pada objek input individual
Secara default, PowerShell menampilkan pesan kesalahan dan melanjutkan eksekusi.
# Non-terminating error: the pipeline continues after the failure
'file1.txt', 'noSuchFile.txt', 'file3.txt' | ForEach-Object {
Get-Content $_ -ErrorAction Continue
}
Dalam contoh ini, Get-Content melaporkan kesalahan yang tidak mengakhiri lalu noSuchFile.txt melanjutkan pemrosesan file3.txt.
Kesalahan yang tidak mengakhiri tidak memicu catch atau trap secara default.
Kesalahan penghentian pernyataan
Kesalahan penghentian pernyataan menghentikan pernyataan saat ini (alur) agar tidak berjalan, tetapi eksekusi berlanjut pada pernyataan berikutnya dalam skrip. Kesalahan penghentian pernyataan dihasilkan oleh:
- Metode
$PSCmdlet.ThrowTerminatingError()dalam fungsi lanjutan dan cmdlet yang dikompilasi - Kesalahan mesin seperti
CommandNotFoundException(memanggil perintah yang tidak ada) danParameterBindingException(argumen parameter tidak valid) - Panggilan metode .NET yang melemparkan pengecualian, seperti
[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'
Kesalahan penghentian pernyataan dapat ditangkap oleh try/catch dan trap.
Nota
.ThrowTerminatingError() tidak berkonsultasi dengan -ErrorAction parameter (kecuali untuk Break nilai, yang memasuki debugger). Namun, $ErrorActionPreferenceberlaku untuk kesalahan penghentian pernyataan melalui handler tingkat pernyataan mesin. Misalnya, $ErrorActionPreference = 'SilentlyContinue' dapat menekan kesalahan penghentian pernyataan sehingga skrip berlanjut pada pernyataan berikutnya. Parameter -ErrorAction tidak dapat melakukan ini. Untuk detailnya, lihat Asimetri $ErrorActionPreference.
Kesalahan penghentian skrip
Kesalahan penghentian skrip melepas seluruh tumpukan panggilan. Eksekusi berhenti sepenuhnya kecuali kesalahan tertangkap oleh try/catch blok atau trap pernyataan. Kesalahan penghentian skrip dihasilkan oleh:
- Kata kunci
throw - Mengurai kesalahan (kesalahan sintaks yang mencegah skrip dikompilasi)
- Kesalahan yang tidak mengakhiri peningkatan oleh
-ErrorAction Stopatau$ErrorActionPreference = 'Stop'dalam konteks non-tingkat lanjut. Untuk informasi selengkapnya, lihat Cara kerja eskalasi. - Kegagalan mesin penting tertentu
# 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)'
Kata throw kunci menghasilkan kesalahan penghentian skrip secara default. Namun, $ErrorActionPreferencedapat menekan throw saat diatur ke SilentlyContinue atau Ignore. Saat memanggil fungsi tingkat lanjut dengan -ErrorAction SilentlyContinue, parameter diterjemahkan ke nilai lokal $ErrorActionPreference cakupan, sehingga juga menekan throw di dalam fungsi tersebut.
Nota
Bahkan dengan $ErrorActionPreference = 'Ignore', throw yang ditekan masih mencatat entri di $Error. Nilai Ignore hanya mencegah $Error perekaman untuk kesalahan yang tidak mengakhiri .
Penting
Istilah penghentian pernyataan dan penghentian skrip menjelaskan cakupan dampak, bukan tingkat keparahan kesalahan. Kesalahan penghentian pernyataan menghentikan satu pernyataan. Kesalahan penghentian skrip menghentikan seluruh skrip dan pemanggilnya. Keduanya dapat ditangkap oleh try/catch.
Kesalahan program eksternal
Program eksternal (asli) tidak berpartisipasi dalam sistem kesalahan PowerShell secara langsung. Mereka melaporkan kegagalan melalui kode keluar bukan nol, yang disimpan PowerShell dalam $LASTEXITCODE variabel otomatis.
git clone https://example.com/nonexistent.git 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Error "git failed with exit code $LASTEXITCODE"
}
Secara default, kode keluar bukan nol dari program asli:
- Atur
$?ke$false -
Tidak menghasilkan in
ErrorRecord$Error -
Tidak memicu
catchatautrap
PowerShell 7.3 menambahkan variabel $PSNativeCommandUseErrorActionPreferencepreferensi eksperimental , yang menjadi fitur stabil di 7.4. Ketika Anda mengatur variabel ini ke $true, itu menyebabkan kode keluar bukan nol memancarkan kesalahan non-mengakhiri yang pesannya menyatakan kode keluar tertentu (a NativeCommandExitException). Kesalahan ini menghormati $ErrorActionPreference, jadi mengaturnya untuk Stop mempromosikan kesalahan ke kesalahan penghentian skrip yang dapat ditangkap dengantry/catch .
Variabel status kesalahan
PowerShell mempertahankan beberapa variabel otomatis yang mencerminkan status kesalahan saat ini.
$?
Berisi $true jika operasi terakhir berhasil dan $false jika menghasilkan kesalahan (tidak mengakhiri atau mengakhiri). Untuk perintah asli, $? diatur berdasarkan kode keluar: $true untuk kode 0keluar , $false jika tidak.
Get-Item -Path 'C:\NoSuchFile.txt' 2>$null
$? # False
$Error
Yang ArrayList menyimpan rekaman kesalahan terbaru, dengan kesalahan terbaru di indeks 0. Daftar menyimpan hingga $MaximumErrorCount entri (default 256).
Semua kesalahan penghentian ditambahkan ke $Error. Untuk mengakhiri kesalahan, Ignore menekan tampilan tetapi masih merekam kesalahan di $Error. Semua non-penghentian ditambahkan ke $Error kecuali -ErrorAction Ignore digunakan pada kesalahan yang tidak mengakhiri, yang mencegah tampilan dan perekaman.
$LASTEXITCODE
Berisi kode keluar dari program asli terakhir yang berjalan. Nilai 0 konvensional menunjukkan keberhasilan. Nilai bukan nol menunjukkan kegagalan. Variabel ini tidak terpengaruh oleh kesalahan cmdlet PowerShell.
Mengontrol perilaku kesalahan
Parameter -ErrorAction umum
Parameter -ErrorAction umum mengambil $ErrorActionPreference alih untuk satu perintah. Ini mengontrol bagaimana PowerShell merespons kesalahan yang tidak mengakhiri dari perintah tersebut.
| Nilai | Perilaku |
|---|---|
Continue |
Tampilkan kesalahan dan lanjutkan (default) |
SilentlyContinue |
Sembunyikan tampilan, tambahkan ke $Error, lanjutkan |
Ignore |
Sembunyikan tampilan dan jangan tambahkan ke $Error |
Stop |
Meningkatkan ke kesalahan yang mengakhiri (lihat Cara kerja eskalasi) |
Inquire |
Meminta pengguna untuk membuat keputusan |
Break |
Masukkan debugger |
-ErrorAction tidak mengubah perilaku kesalahan yang dihasilkan oleh $PSCmdlet.ThrowTerminatingError(). Kesalahan tersebut selalu mengakhiri pernyataan terlepas dari preferensi pemanggil.
Variabel $ErrorActionPreference
Variabel $ErrorActionPreference preferensi berlaku untuk semua perintah dalam cakupan saat ini dan cakupan anak. Ini menerima nilai yang sama dengan -ErrorAction.
$ErrorActionPreference = 'Stop'
# All non-terminating errors in this scope now become terminating
Write-Error 'This now throws' # Generates ActionPreferenceStopException
Ketika -ErrorAction ditentukan pada perintah, itu lebih diutamakan untuk $ErrorActionPreference perintah tersebut.
Cara kerja eskalasi
Saat -ErrorAction Stop atau $ErrorActionPreference = 'Stop' berlaku, PowerShell mengonversi kesalahan yang tidak mengakhiri kesalahan menjadi mengakhiri kesalahan menggunakan mekanisme berikut:
- Cmdlet memanggil
WriteError()secara internal untuk memancarkan kesalahan yang tidak mengakhiri. - Mesin memeriksa preferensi efektif
ErrorActionuntuk perintah. - Karena preferensinya adalah
Stop, mesin membuat yangActionPreferenceStopExceptionmembungkus rekaman kesalahan asli. - Jika tertangkap oleh
catch, informasi kesalahan asli dapat diakses melalui$_.Exception.ErrorRecord.
Cakupan kesalahan yang diluaskan tergantung pada konteks:
- Dalam skrip, fungsi, atau blok skrip non-tingkat lanjut , pengaturan
$ErrorActionPreference = 'Stop'meningkat menjadi kesalahan penghentian skrip . Kesalahan menyebarkan tumpukan panggilan. - Dalam fungsi lanjutan dan blok skrip (dengan
[CmdletBinding()]), kesalahan tetap mengakhiri pernyataan. Eksekusi berlanjut pada pernyataan berikutnya setelah panggilan. - Meneruskan
-ErrorAction Stopke fungsi tingkat lanjut memiliki efek yang sama dengan pengaturan$ErrorActionPreference = 'Stop'di dalamnya, karena-ErrorActionditerjemahkan ke nilai lingkup lokal$ErrorActionPreference.
Contoh eskalasi
NON-tingkat lanjut: penghentian skrip ('setelah' TIDAK mencetak)
& { param() $ErrorActionPreference = 'Stop' 1/0 # Divide by zero error } 2>$null 'after'ADVANCED: statement-terminating ('after' DOES print)
& { [CmdletBinding()] param() $ErrorActionPreference = 'Stop' 1/0 # Divide by zero error } 2>$null 'after'Tanpa
-ErrorAction Stop: tidak mengakhiri, tangkapan tidak berjalantry { Write-Error 'This is non-terminating' Write-Output 'Execution continues' } catch { Write-Output "Caught: $_" # Not reached }Dengan
-ErrorAction Stop: meningkat ke penghentiantry { Write-Error 'This becomes terminating' -ErrorAction Stop } catch { Write-Output "Caught: $_" # Reached }
Kesalahan yang diluaskan dapat ditangkap oleh jenis pengecualian aslinya. Mesin membuka bungkus untuk menemukan pengecualian yang mendasar ActionPreferenceStopException :
try {
Get-Item -Path 'C:\NoSuchFile.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "File not found: $($_.Exception.Message)"
}
$ErrorActionPreference Asimetri
Parameter -ErrorAction dan $ErrorActionPreference variabel berulah secara berbeda dengan mengakhiri kesalahan. Penting untuk memahami asimetri ini:
-ErrorActionhanya memengaruhi kesalahan yang tidak mengakhiri . Ketika cmdlet memanggil$PSCmdlet.ThrowTerminatingError(),-ErrorActionparameter diabaikan (kecuali untukBreak, yang memasuki debugger). Kesalahan selalu dilemparkan.$ErrorActionPreferencememengaruhi kesalahan yang tidak mengakhiri dan mengakhiri pernyataan. Handler kesalahan tingkat pernyataan mesin membaca$ErrorActionPreference(bukan-ErrorActionparameter) dan dapat menekan kesalahan yang mengakhiri pernyataan saat nilainya adalahSilentlyContinueatauIgnore.
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'
Penting
$ErrorActionPreference tidak dapat menyembunyikan kesalahan yang telah SuppressPromptInInterpreter diatur ke true. Ini selalu menyebar terlepas dari variabel preferensi. Contoh jenis kesalahan ini meliputi:
-
ActionPreferenceStopExceptiondari-ErrorAction Stopeskalasi - Kesalahan di dalam metode kelas PowerShell
PipelineStoppedException
Menangani kesalahan
try/catch/finally
Gunakan try/catch/finally untuk menangani kesalahan penghentian pernyataan dan penghentian skrip. Ketika kesalahan terjadi di dalam try blok, PowerShell mencari blok yang cocok catch . Blok finally selalu berjalan, apakah terjadi kesalahan atau tidak.
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
}
try Di dalam blok, mesin menetapkan bendera internal yang menyebabkan kesalahan non-penghentian yang ditingkatkan oleh -ErrorAction Stop atau $ErrorActionPreference = 'Stop' menyebar ke catch blok. Ini dirancang perilaku, bukan kasus khusus.
Untuk detail sintaks lengkap, lihat about_Try_Catch_Finally.
trap
Pernyataan ini trap menangani penghentian kesalahan pada tingkat cakupan. Ketika kesalahan terjadi di mana saja dalam cakupan penutup, trap blok berjalan.
-
Default (tidak
breakataucontinue): Kesalahan ditampilkan dan eksekusi berlanjut pada pernyataan berikutnya setelah yang menyebabkan kesalahan. -
continuedalam perangkap: Menekan pesan kesalahan dan melanjutkan pada pernyataan berikutnya. -
breakdalam perangkap: Kesalahan menyebar ke cakupan induk.
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'
Untuk detail sintaks lengkap, lihat about_Trap.
Melaporkan kesalahan dalam fungsi dan skrip
Saat menulis fungsi dan skrip, pilih mekanisme pelaporan kesalahan yang cocok dengan tingkat keparahan kegagalan.
Tidak mengakhiri - gunakan Write-Error
Gunakan Write-Error ketika fungsi dapat terus memproses input lain. Ini sesuai untuk fungsi alur yang memproses beberapa objek dan mengalami kegagalan pada item individual.
function Test-Path-Safe {
[CmdletBinding()]
param([Parameter(ValueFromPipeline)][string]$Path)
process {
if (-not (Test-Path $Path)) {
Write-Error "Path not found: $Path"
return
}
$Path
}
}
Nota
Dalam fungsi lanjutan (dengan [CmdletBinding()]), gunakan $PSCmdlet.WriteError() alih-alih Write-Error untuk memastikan bahwa diatur $? dengan benar ke $false dalam cakupan pemanggil.
Write-Error Cmdlet tidak selalu diatur $? dengan benar.
Penghentian pernyataan - gunakan $PSCmdlet.ThrowTerminatingError()
Gunakan $PSCmdlet.ThrowTerminatingError() ketika fungsi tidak dapat dilanjutkan sama sekali tetapi pemanggil harus memutuskan cara menangani kegagalan. Ini adalah pendekatan yang direkomendasikan dalam fungsi lanjutan.
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
}
Setelah kesalahan meninggalkan fungsi, pemanggil memperlakukannya sebagai kesalahan yang tidak mengakhiri secara default. Pemanggil dapat meningkatkannya dengan -ErrorAction Stop.
Penghentian skrip - gunakan throw
Gunakan throw saat pemulihan tidak dimungkinkan dan seluruh skrip harus berhenti.
$config = Get-Content 'config.json' -ErrorAction SilentlyContinue |
ConvertFrom-Json
if (-not $config) {
throw 'Cannot proceed without a valid configuration file.'
}
Mekanisme mana yang akan digunakan
- Saat memproses beberapa input di mana beberapa mungkin gagal, gunakan
Write-Erroratau$PSCmdlet.WriteError(). - Jika fungsi tidak dapat dilanjutkan, gunakan
$PSCmdlet.ThrowTerminatingError()dan biarkan pemanggil memutuskan cara menanganinya. - Jika seluruh skrip harus segera berhenti, gunakan
throw.
Ringkasan jenis kesalahan
Tabel berikut ini meringkas properti dan perilaku dari berbagai jenis kesalahan di PowerShell.
Kesalahan non-penghentian
Kesalahan yang tidak mengakhiri dapat dihasilkan oleh Write-Error atau $PSCmdlet.WriteError().
| Attribute | Deskripsi |
|---|---|
| Cakupan dampak | Alur berlanjut |
Tertangkap oleh catch |
Tidak (kecuali dinaikkan) |
Tertangkap oleh trap |
Tidak (kecuali dinaikkan) |
Ditambahkan ke $Error |
Ya (kecuali Ignore) |
Atur $? ke $false |
Yes |
Dipengaruhi oleh -ErrorAction |
Yes |
Dipengaruhi oleh $ErrorActionPreference |
Yes |
Kesalahan penghentian pernyataan
Kesalahan penghentian pernyataan dapat dihasilkan oleh ThrowTerminatingError(), kesalahan mesin, pengecualian metode .NET, atau -ErrorAction Stop dalam konteks lanjutan.
| Attribute | Deskripsi |
|---|---|
| Cakupan dampak | Pernyataan saat ini berhenti; skrip berlanjut |
Tertangkap oleh catch |
Yes |
Tertangkap oleh trap |
Yes |
Ditambahkan ke $Error |
Yes |
Atur $? ke $false |
Yes |
Dipengaruhi oleh -ErrorAction |
Tidak (Break hanya) |
Dipengaruhi oleh $ErrorActionPreference |
Ya (dapat menekan) |
Kesalahan penghentian skrip
Kesalahan penghentian skrip dapat dihasilkan oleh throw, mengurai kesalahan, atau -ErrorAction Stop dalam konteks non-tingkat lanjut.
| Attribute | Deskripsi |
|---|---|
| Cakupan dampak | Memanggil stack unwinds |
Tertangkap oleh catch |
Yes |
Tertangkap oleh trap |
Yes |
Ditambahkan ke $Error |
Yes |
Atur $? ke $false |
Yes |
Dipengaruhi oleh -ErrorAction |
No |
Dipengaruhi oleh $ErrorActionPreference |
throw: Ya (dapat menekan) |
Dipengaruhi oleh $ErrorActionPreference |
Diluaskan: tergantung pada konteks |