Bagikan melalui


Semua yang ingin Anda ketahui tentang pengecualian

Penanganan kesalahan hanyalah bagian dari kehidupan dalam hal menulis kode. Kami sering dapat memeriksa dan memvalidasi kondisi untuk perilaku yang diharapkan. Ketika hal tak terduga terjadi, kita beralih ke penanganan pengecualian. Anda dapat dengan mudah menangani pengecualian yang dihasilkan oleh kode orang lain atau Anda dapat menghasilkan pengecualian Anda sendiri untuk ditangani orang lain.

Nota

Versi asli artikel ini muncul di blog yang ditulis oleh @KevinMarquette. Tim PowerShell berterima kasih kepada Kevin karena telah membagikan konten ini kepada kami. Silakan lihat blognya di PowerShellExplained.com.

Istilah dasar

Kita perlu membahas beberapa istilah dasar sebelum kita melompat ke yang satu ini.

Pengecualian

Pengecualian seperti peristiwa yang dibuat saat penanganan kesalahan normal tidak dapat menangani masalah. Mencoba membagi angka dengan nol atau kehabisan memori adalah contoh sesuatu yang menciptakan pengecualian. Terkadang pembuat kode yang Anda gunakan membuat pengecualian untuk masalah tertentu saat terjadi.

Lempar dan Tangkap

Ketika pengecualian terjadi, kami mengatakan bahwa pengecualian dilemparkan. Untuk menangani pengecualian yang dilemparkan, Anda perlu menangkapnya. Jika pengecualian dilemparkan dan tidak tertangkap oleh sesuatu, skrip berhenti dijalankan.

Tumpukan panggilan

Tumpukan panggilan adalah daftar fungsi yang telah saling memanggil. Ketika fungsi dipanggil, fungsi akan ditambahkan ke tumpukan atau bagian atas daftar. Ketika fungsi keluar atau kembali, fungsi dihapus dari tumpukan.

Ketika pengecualian dilemparkan, tumpukan panggilan tersebut diperiksa agar penangan pengecualian menangkapnya.

Mengakhiri dan tidak menghentikan kesalahan

PowerShell memiliki tiga kategori kesalahan.

  • Kesalahan yang tidak mengakhiri menambahkan kesalahan ke aliran kesalahan tanpa menghentikan eksekusi dan tidak memicu catch. Secara default, Write-Error menghasilkan kesalahan yang tidak mengakhiri.
  • Kesalahan penghentian pernyataan menghentikan pernyataan saat ini tetapi memungkinkan skrip untuk melanjutkan pada pernyataan berikutnya. Kesalahan penghentian pernyataan dapat dihasilkan dari kesalahan mesin, $PSCmdlet.ThrowTerminatingError(), atau pengecualian metode .NET.
  • Kesalahan yang mengakhiri skrip membongkar seluruh tumpukan panggilan. Kesalahan penghentian skrip dapat dihasilkan oleh throw, mengurai kesalahan, atau -ErrorAction Stop eskalasi.

Kesalahan penghentian pernyataan dan penghentian skrip dapat ditangkap oleh try/catch. Untuk referensi komprehensif, lihat about_Error_Handling.

Menelan pengecualian

Ini adalah ketika Anda menangkap kesalahan hanya untuk mengabaikannya. Lakukan ini dengan hati-hati karena dapat membuat masalah pemecahan masalah menjadi sangat sulit.

Sintaks perintah dasar

Berikut adalah gambaran umum singkat sintaks penanganan pengecualian dasar yang digunakan dalam PowerShell.

Lempar

Untuk membuat event pengecualian kita sendiri, kita melempar pengecualian dengan menggunakan throw kata kunci.

function Start-Something
{
    throw "Bad thing happened"
}

Ini membuat pengecualian runtime yang merupakan kesalahan penghentian skrip. Ini ditangani oleh catch dalam fungsi panggilan atau keluar dari skrip dengan pesan seperti berikut.

PS> Start-Something

Bad thing happened
At line:1 char:1
+ throw "Bad thing happened"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Bad thing happened:String) [], RuntimeException
    + FullyQualifiedErrorId : Bad thing happened

Write-Error -ErrorAction Berhenti

Saya menyebutkan bahwa Write-Error tidak memunculkan kesalahan penghentian secara default. Jika Anda menentukan -ErrorAction Stop, Write-Error menghasilkan kesalahan penghentian yang dapat ditangani dengan catch.

Write-Error -Message "Houston, we have a problem." -ErrorAction Stop

Terima kasih kepada Lee Dailey karena telah mengingatkan akan penggunaan -ErrorAction Stop dengan cara ini.

Cmdlet -ErrorAction Berhenti

Jika Anda menentukan -ErrorAction Stop pada fungsi atau cmdlet tingkat lanjut, itu mengubah semua Write-Error pernyataan menjadi mengakhiri kesalahan yang menghentikan eksekusi atau yang dapat ditangani oleh catch.

Start-Something -ErrorAction Stop

Untuk informasi selengkapnya tentang parameter ErrorAction , lihat about_CommonParameters. Untuk informasi selengkapnya tentang variabel $ErrorActionPreference, lihat about_Preference_Variables.

Coba/Tangkap

Cara kerja penanganan pengecualian di PowerShell (dan banyak bahasa lainnya) adalah Anda terlebih dahulu try sebuah bagian kode dan jika terjadi kesalahan, Anda bisa catch itu. Berikut adalah sampel cepat.

try
{
    Start-Something
}
catch
{
    Write-Output "Something threw an exception"
    Write-Output $_
}

try
{
    Start-Something -ErrorAction Stop
}
catch
{
    Write-Output "Something threw an exception or used Write-Error"
    Write-Output $_
}

catch Skrip hanya berjalan jika ada kesalahan fatal. Jika try berhasil dieksekusi, maka melewati catch. Anda dapat mengakses informasi pengecualian di catch blok menggunakan $_ variabel .

Coba/Akhirnya

Terkadang Anda tidak perlu menangani kesalahan tetapi masih memerlukan beberapa kode untuk dijalankan jika terjadi pengecualian atau tidak. finally Skrip melakukan hal itu.

Lihat contoh ini:

$command = [System.Data.SqlClient.SqlCommand]::new(queryString, connection)
$command.Connection.Open()
$command.ExecuteNonQuery()
$command.Connection.Close()

Setiap kali Anda membuka atau menyambungkan ke sumber daya, Anda harus menutupnya. Jika ExecuteNonQuery() menimbulkan pengecualian, koneksi tidak ditutup. Berikut adalah kode yang sama di dalam try/finally blok.

$command = [System.Data.SqlClient.SqlCommand]::new(queryString, connection)
try
{
    $command.Connection.Open()
    $command.ExecuteNonQuery()
}
finally
{
    $command.Connection.Close()
}

Dalam contoh ini, koneksi ditutup jika ada kesalahan. Ini juga akan ditutup jika tidak ada kesalahan. finally Skrip berjalan setiap saat.

Karena Anda tidak menangkap pengecualian tersebut, pengecualian itu akan tetap diteruskan ke tumpukan panggilan.

Coba/Tangkap/Akhirnya

Sepenuhnya sah untuk menggunakan catch dan finally bersama-sama. Sebagian besar waktu Anda akan menggunakan satu atau yang lain, tetapi Anda mungkin menemukan skenario di mana Anda menggunakan keduanya.

$PSItem

Sekarang setelah kita memahami dasar-dasarnya, kita bisa menggali lebih dalam.

catch Di dalam blok, ada variabel otomatis ($PSItem atau $_) jenis ErrorRecord yang berisi detail tentang pengecualian. Berikut adalah gambaran umum singkat tentang beberapa properti utama.

Untuk contoh ini, saya menggunakan jalur ReadAllText yang tidak valid untuk menghasilkan pengecualian ini.

[System.IO.File]::ReadAllText( '\\test\no\filefound.log')

PSItem.ToString()

Ini memberi Anda pesan terbersih untuk digunakan dalam pengelogan dan output umum. ToString() secara otomatis dipanggil jika $PSItem ditempatkan di dalam string.

catch
{
    Write-Output "Ran into an issue: $($PSItem.ToString())"
}

catch
{
    Write-Output "Ran into an issue: $PSItem"
}

$PSItem.InvocationInfo

Properti ini berisi informasi tambahan yang dikumpulkan oleh PowerShell tentang fungsi atau skrip tempat pengecualian dilemparkan. Berikut adalah InvocationInfo dari pengecualian sampel yang saya buat.

PS> $PSItem.InvocationInfo | Format-List *

MyCommand             : Get-Resource
BoundParameters       : {}
UnboundArguments      : {}
ScriptLineNumber      : 5
OffsetInLine          : 5
ScriptName            : C:\blog\throwerror.ps1
Line                  :     Get-Resource
PositionMessage       : At C:\blog\throwerror.ps1:5 char:5
                        +     Get-Resource
                        +     ~~~~~~~~~~~~
PSScriptRoot          : C:\blog
PSCommandPath         : C:\blog\throwerror.ps1
InvocationName        : Get-Resource

Detail penting di sini menunjukkan ScriptName, Line kode dan ScriptLineNumber tempat pemanggilan dimulai.

$PSItem.ScriptStackTrace

Properti ini menunjukkan urutan panggilan fungsi yang membawa Anda ke kode tempat pengecualian dibuat.

PS> $PSItem.ScriptStackTrace
at Get-Resource, C:\blog\throwerror.ps1: line 13
at Start-Something, C:\blog\throwerror.ps1: line 5
at <ScriptBlock>, C:\blog\throwerror.ps1: line 18

Saya hanya melakukan panggilan ke fungsi dalam skrip yang sama tetapi ini akan melacak panggilan jika beberapa skrip terlibat.

$PSItem.Exception

Ini adalah pengecualian yang sebenarnya terjadi.

$PSItem.Exception.Message

Ini adalah pesan umum yang menjelaskan pengecualian dan merupakan titik awal yang baik saat pemecahan masalah. Sebagian besar pengecualian memiliki pesan default tetapi juga dapat diatur ke sesuatu yang kustom saat pengecualian dilemparkan.

PS> $PSItem.Exception.Message

Exception calling "ReadAllText" with "1" argument(s): "The network path was not found."

Ini juga merupakan pesan yang dikembalikan saat memanggil $PSItem.ToString() jika tidak ada satu set pada ErrorRecord.

$PSItem.Exception.InnerException

Pengecualian dapat berisi pengecualian internal. Ini sering terjadi ketika kode yang Anda panggil menangkap pengecualian dan melemparkan pengecualian yang berbeda. Pengecualian asli ditempatkan di dalam pengecualian baru.

PS> $PSItem.Exception.InnerExceptionMessage
The network path was not found.

Saya akan membahas ini kembali nanti ketika saya berbicara tentang melempar ulang pengecualian.

$PSItem.Exception.StackTrace

Ini adalah StackTrace untuk pengecualian. Saya menunjukkan di ScriptStackTrace atas, tetapi yang ini untuk pemanggilan ke kode terkelola.

at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean
 useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs,
 String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32
 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean
 checkHost)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks,
 Int32 bufferSize, Boolean checkHost)
at System.IO.File.InternalReadAllText(String path, Encoding encoding, Boolean checkHost)
at CallSite.Target(Closure , CallSite , Type , String )

Anda hanya mendapatkan jejak tumpukan ini ketika event dilempar dari kode terkelola. Saya memanggil fungsi .NET Framework secara langsung sehingga hanya itu yang dapat kita lihat dalam contoh ini. Umumnya ketika Anda melihat stack trace, Anda mencari tempat kode Anda berhenti dan pemanggilan sistem dimulai.

Bekerja dengan pengecualian

Ada lebih banyak pengecualian daripada sintaks dasar dan properti pengecualian.

Menangkap pengecualian yang diketik

Anda dapat selektif dengan pengecualian yang Anda tangkap. Pengecualian memiliki jenis dan Anda dapat menentukan jenis pengecualian yang ingin Anda tangkap.

try
{
    Start-Something -Path $path
}
catch [System.IO.FileNotFoundException]
{
    Write-Output "Could not find $path"
}
catch [System.IO.IOException]
{
        Write-Output "IO error with the file: $path"
}

Jenis pengecualian diperiksa untuk setiap catch blok hingga ditemukan yang cocok dengan pengecualian Anda. Penting untuk disadari bahwa pengecualian dapat diwarisi dari pengecualian lain. Dalam contoh di atas, FileNotFoundException mewarisi dari IOException. Jadi jika yang IOException pertama, maka itu akan dipanggil sebagai gantinya. Hanya satu blok tangkapan yang dipanggil bahkan jika ada beberapa kecocokan.

Jika kita memiliki System.IO.PathTooLongException, IOException akan cocok tetapi jika kita memiliki InsufficientMemoryException maka tidak ada yang akan menangkapnya dan akan menyebar ke atas tumpukan.

Menangkap beberapa jenis sekaligus

Dimungkinkan untuk menangkap beberapa jenis pengecualian dengan pernyataan yang sama catch .

try
{
    Start-Something -Path $path -ErrorAction Stop
}
catch [System.IO.DirectoryNotFoundException],[System.IO.FileNotFoundException]
{
    Write-Output "The path or file was not found: [$path]"
}
catch [System.IO.IOException]
{
    Write-Output "IO error with the file: [$path]"
}

Terima kasih Redditor u/Sheppard_Ra telah menyarankan penambahan ini.

Melemparkan pengecualian yang diketik

Anda dapat melemparkan pengecualian yang diketik di PowerShell. Alih-alih memanggil throw dengan string:

throw "Could not find: $path"

Gunakan akselerator pengecualian seperti ini:

throw [System.IO.FileNotFoundException] "Could not find: $path"

Tetapi Anda harus menentukan pesan ketika Anda melakukannya dengan cara itu.

Anda juga dapat membuat instance baru untuk pengecualian yang akan dilemparkan. Pesan bersifat opsional ketika Anda melakukan ini karena sistem memiliki pesan default untuk semua pengecualian bawaan.

throw [System.IO.FileNotFoundException]::new()
throw [System.IO.FileNotFoundException]::new("Could not find path: $path")

Jika Anda tidak menggunakan PowerShell 5.0 atau yang lebih tinggi, Anda harus menggunakan pendekatan lama New-Object.

throw (New-Object -TypeName System.IO.FileNotFoundException )
throw (New-Object -TypeName System.IO.FileNotFoundException -ArgumentList "Could not find path: $path")

Dengan menggunakan pengecualian yang diketik, Anda (atau orang lain) dapat menangkap pengecualian berdasarkan jenis seperti yang disebutkan di bagian sebelumnya.

Write-Error -Exception (Tulis-Kesalahan -Pengecualian)

Kita dapat menambahkan pengecualian yang diketik ini ke Write-Error dan kita masih dapat mengidentifikasi kesalahan berdasarkan tipe pengecualian. Gunakan Write-Error seperti dalam contoh ini:

# with normal message
Write-Error -Message "Could not find path: $path" -Exception ([System.IO.FileNotFoundException]::new()) -ErrorAction Stop

# With message inside new exception
Write-Error -Exception ([System.IO.FileNotFoundException]::new("Could not find path: $path")) -ErrorAction Stop

# Pre PS 5.0
Write-Error -Exception ([System.IO.FileNotFoundException]"Could not find path: $path") -ErrorAction Stop

Write-Error -Message "Could not find path: $path" -Exception (New-Object -TypeName System.IO.FileNotFoundException) -ErrorAction Stop

Lalu kita dapat menangkapnya dengan cara ini:

catch [System.IO.FileNotFoundException]
{
    Write-Log $PSItem.ToString()
}

Daftar besar pengecualian .NET

Saya menyusun daftar master dengan bantuan komunitas Reddit r/PowerShell yang berisi ratusan pengecualian .NET untuk melengkapi posting ini.

Saya mulai dengan mencari daftar itu untuk pengecualian yang terasa cocok untuk situasi saya. Anda harus mencoba menggunakan pengecualian di namespace dasar System .

Pengecualian adalah objek

Jika Anda mulai menggunakan banyak pengecualian yang diketik, ingatlah bahwa itu adalah objek. Pengecualian yang berbeda memiliki konstruktor dan properti yang berbeda. Jika kita melihat dokumentasi FileNotFoundException untuk System.IO.FileNotFoundException, kita melihat bahwa kita dapat meneruskan pesan dan jalur file.

[System.IO.FileNotFoundException]::new("Could not find file", $path)

Dan memiliki FileName properti yang mengekspos jalur file tersebut.

catch [System.IO.FileNotFoundException]
{
    Write-Output $PSItem.Exception.FileName
}

Anda harus berkonsultasi dengan dokumentasi .NET untuk konstruktor dan properti objek lainnya.

Melemparkan kembali pengecualian

Jika semua yang akan Anda lakukan di blok catch Anda adalah throw pengecualian yang sama, maka jangan catch. Anda seharusnya hanya catch pengecualian yang Anda rencanakan untuk ditangani atau melakukan tindakan saat itu terjadi.

Ada kalanya Anda ingin menangani pengecualian, tetapi melemparkan kembali pengecualian tersebut agar dapat ditangani pada tahap berikutnya. Kita dapat menulis pesan atau mencatat masalah yang dekat dengan lokasi ditemukannya, namun menangani masalahnya di bagian atas tumpukan.

catch
{
    Write-Log $PSItem.ToString()
    throw $PSItem
}

Cukup menarik, kita dapat memanggil throw dari dalam catch dan melemparkan kembali pengecualian saat ini.

catch
{
    Write-Log $PSItem.ToString()
    throw
}

Kami ingin melemparkan kembali pengecualian untuk mempertahankan informasi eksekusi asli seperti skrip sumber dan nomor baris. Jika kita melemparkan pengecualian baru pada saat ini, hal itu akan menyembunyikan tempat pengecualian tersebut dimulai.

Melemparkan kembali pengecualian baru

Jika Anda menangkap pengecualian tetapi Anda ingin melemparkan yang berbeda, maka Anda harus menyarangkan pengecualian asli di dalam yang baru. Ini memungkinkan seseorang di bagian bawah hierarki untuk mengaksesnya sebagai $PSItem.Exception.InnerException.

catch
{
    throw [System.MissingFieldException]::new('Could not access field',$PSItem.Exception)
}

$PSCmdlet.ThrowTerminatingError()

Satu hal yang tidak saya sukai tentang penggunaan throw untuk pengecualian mentah adalah bahwa pesan kesalahan menunjuk pada throw pernyataan dan menunjukkan bahwa baris adalah tempat masalahnya.

Unable to find the specified file.
At line:31 char:9
+         throw [System.IO.FileNotFoundException]::new()
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], FileNotFoundException
    + FullyQualifiedErrorId : Unable to find the specified file.

Pesan kesalahan yang memberi tahu saya bahwa skrip saya rusak karena saya memanggil < c0 /> pada baris 31 adalah pesan yang buruk untuk dilihat oleh pengguna skrip Anda. Ini tidak memberi tahu mereka sesuatu yang berguna.

Dexter Dhami menunjukkan bahwa saya dapat menggunakan ThrowTerminatingError() untuk memperbaiki itu.

$PSCmdlet.ThrowTerminatingError(
    [System.Management.Automation.ErrorRecord]::new(
        ([System.IO.FileNotFoundException]"Could not find $Path"),
        'My.ID',
        [System.Management.Automation.ErrorCategory]::OpenError,
        $MyObject
    )
)

Jika kita berasumsi bahwa ThrowTerminatingError() itu dipanggil di dalam fungsi yang disebut Get-Resource, maka ini adalah kesalahan yang akan kita lihat.

Get-Resource : Could not find C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework\.NETPortable\v4.6\System.IO.xml
At line:6 char:5
+     Get-Resource -Path $Path
+     ~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (:) [Get-Resource], FileNotFoundException
    + FullyQualifiedErrorId : My.ID,Get-Resource

Apakah Anda melihat bagaimana hal itu menunjuk ke Get-Resource fungsi sebagai sumber masalah? Itu memberi tahu pengguna sesuatu yang berguna.

Karena $PSItem adalah ErrorRecord, kita juga dapat menggunakan ThrowTerminatingError dengan cara ini untuk melempar ulang.

catch
{
    $PSCmdlet.ThrowTerminatingError($PSItem)
}

Ini mengubah asal kesalahan ke Cmdlet dan menyembunyikan bagian internal dari fungsi Anda untuk pengguna Cmdlet Anda.

Pengaruh try/catch terhadap propagasi kesalahan

Di dalam blok try, PowerShell menetapkan penanda internal yang menyebabkan semua kesalahan penghentian pernyataan diteruskan ke blok catch. Ini secara desain, bukan kotak sudut. Contoh berikut menunjukkan perilaku ini.

function Start-Something { 1/(1-1) }

Di luar try/catch, kesalahan penghentian pernyataan dari cakupan anak tidak menghentikan cakupan induk. Berikut adalah fungsi yang menghasilkan pembagian dengan pengecualian runtime nol.

Panggil seperti ini untuk melihat kesalahan yang dilaporkan saat skrip berlanjut.

&{ Start-Something; Write-Output "We did it. Send Email" }

Tetapi ketika menempatkan kode yang sama di dalam try/catch, kesalahan menyebar ke blok catch.

try {
    &{ Start-Something; Write-Output "We did it. Send Email" }
} catch {
    Write-Output "Notify Admin to fix error and send email"
}

Kesalahan ditangkap dan akibatnya Write-Output di dalam blok skrip tidak dijalankan. Ini adalah perilaku standar dari try/catch — semua kesalahan penghentian dalam blok try tertangkap, baik yang berasal dari cakupan saat ini maupun dalam cakupan turunan.

$PSCmdlet.ThrowTerminatingError() di dalam try/catch

$PSCmdlet.ThrowTerminatingError() membuat kesalahan penghentian pernyataan dalam cmdlet. Setelah kesalahan keluar dari cmdlet, pemanggil memperlakukannya sebagai error yang tidak mematikan secara default. Pemanggil dapat meningkatkannya kembali ke kesalahan penghentian dengan menggunakan -ErrorAction Stop atau memanggilnya dari dalam try/catch blok.

Templat fungsi publik

Satu hal terakhir yang saya ambil dari percakapan saya dengan Kirk Munro adalah bahwa ia menempatkan blok try/catch di dalam setiap blok begin, process dan end di semua fungsi lanjutnya. Dalam blok tangkap generik tersebut, dia memiliki satu baris menggunakan $PSCmdlet.ThrowTerminatingError($PSItem) untuk menangani semua pengecualian yang keluar dari fungsinya.

function Start-Something
{
    [CmdletBinding()]
    param()

    process
    {
        try {
            ...
        } catch {
            $PSCmdlet.ThrowTerminatingError($PSItem)
        }
    }
}

Karena semuanya ada dalam pernyataan try di dalam fungsinya, semuanya bertindak secara konsisten. Ini juga memberikan kesalahan bersih kepada pengguna akhir yang menyembunyikan kode internal dari kesalahan yang dihasilkan.

Perangkap

Saya berfokus pada try/catch aspek pengecualian. Tapi ada satu fitur lama yang perlu saya sebutkan sebelum kita menyelesaikan pembicaraan ini.

Sebuah trap ditempatkan dalam skrip atau fungsi untuk menangkap semua pengecualian yang terjadi dalam cakupan tersebut. Ketika pengecualian terjadi, kode dalam trap dijalankan dan kemudian kode normal berlanjut. Jika beberapa pengecualian terjadi, maka perangkap dipanggil berulang-berulang.

trap
{
    Write-Log $PSItem.ToString()
}

throw [System.Exception]::new('first')
throw [System.Exception]::new('second')
throw [System.Exception]::new('third')

Saya pribadi belum pernah mengadopsi pendekatan ini tetapi saya dapat melihat nilai dari skrip admin atau pengontrol yang mencatat pengecualian apa pun dan semua, namun tetap melanjutkan eksekusi.

Menutup komentar

Menambahkan penanganan pengecualian yang tepat ke skrip Anda tidak hanya membuatnya lebih stabil, tetapi juga memudahkan Anda untuk memecahkan masalah pengecualian tersebut.

Saya menghabiskan banyak waktu berbicara throw karena itu adalah konsep inti ketika berbicara tentang penanganan pengecualian. PowerShell juga memberi kami Write-Error yang menangani semua situasi di mana Anda akan menggunakan throw. Jadi jangan berpikir bahwa Anda perlu menggunakan throw setelah membaca ini.

Sekarang setelah saya meluangkan waktu untuk menulis tentang penanganan pengecualian dalam detail ini, saya akan beralih ke menggunakan Write-Error -Stop untuk menghasilkan kesalahan dalam kode saya. Saya juga akan mengambil saran Kirk dan membuat ThrowTerminatingError handler pengecualian goto saya untuk setiap fungsi.