Try...Catch...Finally Pernyataan (Visual Basic)
Menyediakan cara untuk menangani beberapa atau semua kemungkinan kesalahan yang mungkin terjadi pada blok kode tertentu, saat masih menjalankan kode.
Sintaks
Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ]
End Try
Generator
Term | Definisi |
---|---|
tryStatements |
Opsional. Pernyataan tempat kesalahan dapat terjadi. Dapat berupa pernyataan majemuk. |
Catch |
Opsional. Beberapa blok Catch diizinkan. Jika pengecualian terjadi saat memproses blok Try , setiap pernyataan Catch diperiksa dalam urutan tekstual untuk menentukan apakah pernyataan menangani pengecualian, dengan exception mewakili pengecualian yang telah dimunculkan. |
exception |
Opsional. Nama variabel apa saja. Nilai awal exception adalah nilai kesalahan yang dimunculkan. Digunakan dengan Catch untuk menentukan kesalahan yang ditangkap. Jika dihilangkan, pernyataan Catch menangkap pengecualian apa pun. |
type |
Opsional. Tentukan jenis filter kelas. Jika nilai exception adalah jenis yang ditentukan oleh type atau jenis turunan, pengidentifikasi menjadi terikat ke objek pengecualian. |
When |
Opsional. Pernyataan Catch dengan klausul When menangkap pengecualian hanya ketika expression mengevaluasi ke True . Klausul When diterapkan hanya setelah memeriksa jenis pengecualian, dan expression dapat merujuk ke pengidentifikasi yang mewakili pengecualian. |
expression |
Opsional. Harus dapat dikonversi secara implisit ke Boolean . Semua ekspresi yang menjelaskan filter generik. Biasanya digunakan untuk memfilter berdasarkan nomor kesalahan. Digunakan dengan kata kunci When untuk menentukan keadaan saat kesalahan ditangkap. |
catchStatements |
Opsional. Pernyataan untuk menangani kesalahan yang terjadi di blok Try terkait. Dapat berupa pernyataan majemuk. |
Exit Try |
Opsional. Kata kunci yang keluar dari struktur Try...Catch...Finally . Eksekusi dilanjutkan dengan kode segera setelah pernyataan End Try . Pernyataan Finally akan tetap dijalankan. Tidak diizinkan di blok Finally . |
Finally |
Opsional. Blok Finally selalu dijalankan saat eksekusi meninggalkan bagian mana pun dari pernyataan Try...Catch . |
finallyStatements |
Opsional. Pernyataan yang dijalankan setelah semua pemrosesan kesalahan lainnya terjadi. |
End Try |
Hentikan struktur Try...Catch...Finally . |
Keterangan
Jika Anda mengharapkan pengecualian tertentu mungkin terjadi selama bagian kode tertentu, letakkan kode di blok Try
dan gunakan blok Catch
untuk mempertahankan kontrol dan menangani pengecualian jika pengecualian muncul.
Pernyataan Try…Catch
terdiri dari blok Try
yang diikuti oleh satu atau beberapa klausul Catch
, yang menentukan penangan untuk berbagai pengecualian. Saat pengecualian dimunculkan ke dalam blok Try
, Visual Basic mencari pernyataan Catch
yang menangani pengecualian. Jika pernyataan Catch
yang cocok tidak ditemukan, Visual Basic memeriksa metode yang memanggil metode saat ini, dan seterusnya hingga ke tumpukan panggilan. Jika tidak ada blok Catch
yang ditemukan, Visual Basic menampilkan pesan pengecualian yang tidak ditangani kepada pengguna dan menghentikan eksekusi program.
Anda dapat menggunakan lebih dari satu pernyataan Catch
dalam pernyataan Try…Catch
. Jika Anda melakukan ini, urutan klausul Catch
penting karena diperiksa secara berurutan. Catch pengecualian yang lebih spesifik sebelum yang kurang spesifik.
Kondisi pernyataan Catch
berikut adalah yang paling tidak spesifik, dan akan menangkap semua pengecualian yang berasal dari kelas Exception. Anda biasanya harus menggunakan salah satu variasi ini sebagai blok Catch
terakhir dalam struktur Try...Catch...Finally
, setelah menangkap semua pengecualian spesifik yang Anda harapkan. Alur kontrol tidak akan pernah mencapai blok Catch
yang mengikuti salah satu dari variasi ini.
type
adalahException
, misalnya:Catch ex As Exception
Pernyataan tidak memiliki variabel
exception
, misalnya:Catch
Saat pernyataan Try…Catch…Finally
disarangkan di blok Try
lain, Visual Basic pertama-tama memeriksa setiap pernyataan Catch
di blok Try
terdalam. Jika tidak ditemukan pernyataan Catch
yang cocok, pencarian dilanjutkan ke pernyataan Catch
dari blok Try…Catch…Finally
luar.
Variabel lokal dari blok Try
tidak tersedia di blok Catch
karena merupakan blok yang terpisah. Jika Anda ingin menggunakan variabel di lebih dari satu blok, deklarasikan variabel di luar struktur Try...Catch...Finally
.
Tip
Pernyataan Try…Catch…Finally
tersedia sebagai cuplikan kode IntelliSense. Di Manajer Cuplikan Kode, perluas Pola Kode - Jika, Untuk Setiap, TryCatch, Properti, dll, lalu Penanganan Kesalahan (Pengecualian). Untuk informasi selengkapnya, lihat Cuplikan Kode.
Finally blok
Jika Anda memiliki satu atau beberapa pernyataan yang harus dijalankan sebelum Anda keluar dari struktur Try
, gunakan blok Finally
. Kontrol diteruskan ke blok Finally
tepat sebelum kontrol diteruskan dari struktur Try…Catch
. Hal ini berlaku bahkan jika pengecualian terjadi di mana saja di dalam struktur Try
.
Blok Finally
berguna untuk menjalankan kode apa pun yang harus dijalankan meskipun terdapat pengecualian. Kontrol diteruskan ke blok Finally
terlepas dari cara blok Try...Catch
keluar.
Kode di blok Finally
berjalan meskipun kode Anda menemukan pernyataan Return
di blok Try
atau Catch
. Kontrol tidak diteruskan dari blok Try
atau Catch
ke blok Finally
yang sesuai dalam kasus berikut:
Pernyataan End ditemukan di blok
Try
atauCatch
.StackOverflowException dimunculkan dalam blok
Try
atauCatch
.
Tidak valid untuk mentransfer eksekusi secara eksplisit ke dalam blok Finally
. Mentransfer eksekusi dari blok Finally
tidak valid, kecuali melalui pengecualian.
Jika pernyataan Try
tidak berisi setidaknya satu blok Catch
, pernyataan tersebut harus berisi blok Finally
.
Tip
Jika Anda tidak harus menangkap pengecualian tertentu, pernyataan Using
berperilaku seperti blok Try…Finally
, dan menjamin pembuangan sumber daya, terlepas dari cara Anda keluar dari blok. Hal ini berlaku bahkan dengan pengecualian yang tidak ditangani. Untuk informasi selengkapnya, lihat Pernyataan Using.
Argumen pengecualian
Blok Catch
argumen exception
adalah instans dari kelas Exception atau kelas yang diturunkan dari kelas Exception
. Instans kelas Exception
sesuai dengan kesalahan yang terjadi di blok Try
.
Properti objek Exception
membantu mengidentifikasi penyebab dan lokasi pengecualian. Misalnya, properti StackTrace mencantumkan metode yang dipanggil yang mengarah ke pengecualian, membantu Anda menemukan tempat kesalahan terjadi dalam kode. Message mengembalikan pesan yang menjelaskan pengecualian. HelpLink mengembalikan tautan ke file Bantuan terkait. InnerException mengembalikan objek Exception
yang menyebabkan pengecualian saat ini, atau mengembalikan Nothing
jika tidak ada Exception
asli.
Pertimbangan saat menggunakan Try…Catch
pernyataan
Gunakan pernyataan Try…Catch
hanya untuk menandakan terjadinya peristiwa program yang tidak biasa atau tidak terduga. Alasan untuk ini termasuk yang berikut:
Catchpengecualian ing pada run time membuat overhead tambahan, dan kemungkinan lebih lambat daripada pra-pemeriksaan untuk menghindari pengecualian.
Jika blok
Catch
tidak ditangani dengan benar, pengecualian mungkin tidak dilaporkan dengan benar kepada pengguna.Penanganan pengecualian membuat program menjadi lebih kompleks.
Anda tidak selalu memerlukan pernyataan Try…Catch
untuk memeriksa kondisi yang mungkin terjadi. Contoh berikut memeriksa apakah ada file sebelum mencoba membukanya. Hal ini mengurangi kebutuhan untuk menangkap pengecualian yang dimunculkan oleh metode OpenText.
Private Sub TextFileExample(ByVal filePath As String)
' Verify that the file exists.
If System.IO.File.Exists(filePath) = False Then
Console.Write("File Not Found: " & filePath)
Else
' Open the text file and display its contents.
Dim sr As System.IO.StreamReader =
System.IO.File.OpenText(filePath)
Console.Write(sr.ReadToEnd)
sr.Close()
End If
End Sub
Pastikan bahwa kode di blok Catch
dapat melaporkan pengecualian dengan benar kepada pengguna, baik melalui pengelogan yang aman di alur atau pesan yang sesuai. Jika tidak, pengecualian mungkin tetap tidak diketahui.
Metode asinkron
Jika Anda menandai metode dengan pengubah Asinkron, Anda dapat menggunakan operator Tunggu dalam metode. Pernyataan dengan operator Await
menangguhkan eksekusi metode hingga tugas yang ditunggu selesai. Tugas mewakili pekerjaan yang sedang berlangsung. Saat tugas yang terkait dengan operator Await
selesai, eksekusi dilanjutkan dengan metode yang sama. Untuk informasi selengkapnya, lihat Alur Kontrol di Program Asinkron.
Tugas yang dikembalikan oleh metode Asinkron mungkin berakhir dalam status salah, yang menunjukkan bahwa tugas tersebut selesai karena pengecualian yang tidak ditangani. Tugas juga dapat berakhir dalam status dibatalkan, yang mengakibatkan OperationCanceledException
dimunculkan dari ekspresi tunggu. Untuk menangkap salah satu jenis pengecualian, tempatkan ekspresi Await
yang terkait dengan tugas di blok Try
, dan tangkap pengecualian di blok Catch
. Contoh diberikan nanti dalam topik ini.
Tugas dapat berada dalam status yang gagal karena beberapa pengecualian bertanggung jawab atas kesalahan tugas. Misalnya, tugas mungkin merupakan hasil dari panggilan ke Task.WhenAll. Saat Anda menunggu tugas seperti itu, pengecualian yang tertangkap hanya merupakan salah satu pengecualian, dan Anda tidak dapat memprediksi pengecualian mana yang akan ditangkap. Contoh diberikan nanti dalam topik ini.
Ekspresi Await
tidak boleh berada di dalam blok Catch
atau blok Finally
.
Iterator
Fungsi iterator atau pengakses Get
melakukan perulangan kustom pada koleksi. Iterator menggunakan pernyataan Yield untuk mengembalikan setiap elemen koleksi satu per satu. Anda memanggil fungsi iterator dengan menggunakan Pernyataan For Each...Next.
Pernyataan Yield
dapat berada di dalam blok Try
. Blok Try
yang berisi pernyataan Yield
dapat memiliki blok Catch
, dan dapat memiliki blok Finally
. Misalnya, lihat Try Blokir.
Pernyataan Yield
tidak boleh berada di dalam blok Catch
atau blok Finally
.
Jika isi For Each
(di luar fungsi iterator) memunculkan pengecualian, blok Catch
dalam fungsi iterator tidak dijalankan, tetapi blok Finally
dalam fungsi iterator dijalankan. Blok Catch
di dalam fungsi iterator hanya menangkap pengecualian yang terjadi di dalam fungsi iterator.
Situasi kepercayaan sebagian
Dalam situasi kepercayaan sebagian, seperti aplikasi yang dihosting di berbagi jaringan, Try...Catch...Finally
tidak menangkap pengecualian keamanan yang terjadi sebelum metode yang berisi panggilan dipanggil. Contoh berikut, ketika Anda meletakkannya di berbagi server dan menjalankannya dari sana, menghasilkan kesalahan "System.Security.SecurityException: Request Failed." Untuk informasi selengkapnya tentang pengecualian keamanan, lihat kelas SecurityException.
Try
Process.Start("http://www.microsoft.com")
Catch ex As Exception
Console.WriteLine("Can't load Web page" & vbCrLf & ex.Message)
End Try
Dalam situasi kepercayaan sebagian seperti itu, Anda harus meletakkan pernyataan Process.Start
di Sub
terpisah. Panggilan awal ke Sub
akan gagal. Hal ini memungkinkan Try...Catch
menangkapnya sebelum Sub
yang berisi Process.Start
dimulai dan pengecualian keamanan dibuat.
Contoh
Struktur Try...Catch...Finally
Contoh berikut menggambarkan struktur pernyataan Try...Catch...Finally
.
Public Sub TryExample()
' Declare variables.
Dim x As Integer = 5
Dim y As Integer = 0
' Set up structured error handling.
Try
' Cause a "Divide by Zero" exception.
x = x \ y
' This statement does not execute because program
' control passes to the Catch block when the
' exception occurs.
Console.WriteLine("end of Try block")
Catch ex As Exception
' Show the exception's message.
Console.WriteLine(ex.Message)
' Show the stack trace, which is a list of methods
' that are currently executing.
Console.WriteLine("Stack Trace: " & vbCrLf & ex.StackTrace)
Finally
' This line executes whether or not the exception occurs.
Console.WriteLine("in Finally block")
End Try
End Sub
Pengecualian dalam metode yang dipanggil dari Try
blok
Dalam contoh berikut, metode CreateException
menampilkan NullReferenceException
. Kode yang menghasilkan pengecualian tidak berada dalam blok Try
. Oleh karena itu, metode CreateException
tidak menangani pengecualian. Metode RunSample
memang menangani pengecualian karena panggilan ke metode CreateException
ada di blok Try
.
Contoh tersebut mencakup pernyataan Catch
untuk beberapa jenis pengecualian, diurutkan dari yang paling spesifik hingga yang paling umum.
Public Sub RunSample()
Try
CreateException()
Catch ex As System.IO.IOException
' Code that reacts to IOException.
Catch ex As NullReferenceException
Console.WriteLine("NullReferenceException: " & ex.Message)
Console.WriteLine("Stack Trace: " & vbCrLf & ex.StackTrace)
Catch ex As Exception
' Code that reacts to any other exception.
End Try
End Sub
Private Sub CreateException()
' This code throws a NullReferenceException.
Dim obj = Nothing
Dim prop = obj.Name
' This code also throws a NullReferenceException.
'Throw New NullReferenceException("Something happened.")
End Sub
Catch Pernyataan Kapan
Contoh berikut menunjukkan cara menggunakan pernyataan Catch When
untuk memfilter ungkapan bersyarat. Jika ungkapan bersyarat bernilai True
, kode di blok Catch
berjalan.
Private Sub WhenExample()
Dim i As Integer = 5
Try
Throw New ArgumentException()
Catch e As OverflowException When i = 5
Console.WriteLine("First handler")
Catch e As ArgumentException When i = 4
Console.WriteLine("Second handler")
Catch When i = 5
Console.WriteLine("Third handler")
End Try
End Sub
' Output: Third handler
Pernyataan berlapis Try
Contoh berikut memiliki pernyataan Try…Catch
yang terdapat dalam blok Try
. Blok Catch
bagian dalam memunculkan pengecualian dengan properti InnerException
yang diatur ke pengecualian asli. Blok Catch
luar melaporkan pengecualiannya sendiri dan pengecualian dalam.
Private Sub InnerExceptionExample()
Try
Try
' Set a reference to a StringBuilder.
' The exception below does not occur if the commented
' out statement is used instead.
Dim sb As System.Text.StringBuilder
'Dim sb As New System.Text.StringBuilder
' Cause a NullReferenceException.
sb.Append("text")
Catch ex As Exception
' Throw a new exception that has the inner exception
' set to the original exception.
Throw New ApplicationException("Something happened :(", ex)
End Try
Catch ex2 As Exception
' Show the exception.
Console.WriteLine("Exception: " & ex2.Message)
Console.WriteLine(ex2.StackTrace)
' Show the inner exception, if one is present.
If ex2.InnerException IsNot Nothing Then
Console.WriteLine("Inner Exception: " & ex2.InnerException.Message)
Console.WriteLine(ex2.StackTrace)
End If
End Try
End Sub
Penanganan pengecualian untuk metode asinkron
Contoh berikut menggambarkan penanganan pengecualian untuk metode asinkron. Untuk menangkap pengecualian yang berlaku untuk tugas asinkron, ekspresi Await
ada di blok Try
pemanggil, dan pengecualian ditangkap di blok Catch
.
Batalkan komentar pada baris Throw New Exception
dalam contoh untuk menunjukkan penanganan pengecualian. Pengecualian ditangkap di blok Catch
, properti IsFaulted
tugas diatur ke True
, dan properti Exception.InnerException
tugas diatur ke pengecualian.
Batalkan komentar pada baris Throw New OperationCancelledException
untuk menunjukkan apa yang terjadi saat Anda membatalkan proses asinkron. Pengecualian ditangkap di blok Catch
, dan properti IsCanceled
tugas diatur ke True
. Tetapi, dalam beberapa kondisi yang tidak berlaku untuk contoh ini, IsFaulted
diatur ke True
dan IsCanceled
diatur ke False
.
Public Async Function DoSomethingAsync() As Task
Dim theTask As Task(Of String) = DelayAsync()
Try
Dim result As String = Await theTask
Debug.WriteLine("Result: " & result)
Catch ex As Exception
Debug.WriteLine("Exception Message: " & ex.Message)
End Try
Debug.WriteLine("Task IsCanceled: " & theTask.IsCanceled)
Debug.WriteLine("Task IsFaulted: " & theTask.IsFaulted)
If theTask.Exception IsNot Nothing Then
Debug.WriteLine("Task Exception Message: " &
theTask.Exception.Message)
Debug.WriteLine("Task Inner Exception Message: " &
theTask.Exception.InnerException.Message)
End If
End Function
Private Async Function DelayAsync() As Task(Of String)
Await Task.Delay(100)
' Uncomment each of the following lines to
' demonstrate exception handling.
'Throw New OperationCanceledException("canceled")
'Throw New Exception("Something happened.")
Return "Done"
End Function
' Output when no exception is thrown in the awaited method:
' Result: Done
' Task IsCanceled: False
' Task IsFaulted: False
' Output when an Exception is thrown in the awaited method:
' Exception Message: Something happened.
' Task IsCanceled: False
' Task IsFaulted: True
' Task Exception Message: One or more errors occurred.
' Task Inner Exception Message: Something happened.
' Output when an OperationCanceledException or TaskCanceledException
' is thrown in the awaited method:
' Exception Message: canceled
' Task IsCanceled: True
' Task IsFaulted: False
Menangani beberapa pengecualian dalam metode asinkron
Contoh berikut menggambarkan penanganan pengecualian di mana banyak tugas dapat menghasilkan beberapa pengecualian. Blok Try
memiliki ekspresi Await
untuk tugas yang dikembalikan Task.WhenAll. Tugas selesai ketika tiga tugas yang menerapkan Task.WhenAll selesai.
Masing-masing dari tiga tugas menyebabkan pengecualian. Blok Catch
berulang melalui pengecualian, yang ditemukan di properti Exception.InnerExceptions
dari tugas yang dikembalikan Task.WhenAll
.
Public Async Function DoMultipleAsync() As Task
Dim theTask1 As Task = ExcAsync(info:="First Task")
Dim theTask2 As Task = ExcAsync(info:="Second Task")
Dim theTask3 As Task = ExcAsync(info:="Third Task")
Dim allTasks As Task = Task.WhenAll(theTask1, theTask2, theTask3)
Try
Await allTasks
Catch ex As Exception
Debug.WriteLine("Exception: " & ex.Message)
Debug.WriteLine("Task IsFaulted: " & allTasks.IsFaulted)
For Each inEx In allTasks.Exception.InnerExceptions
Debug.WriteLine("Task Inner Exception: " + inEx.Message)
Next
End Try
End Function
Private Async Function ExcAsync(info As String) As Task
Await Task.Delay(100)
Throw New Exception("Error-" & info)
End Function
' Output:
' Exception: Error-First Task
' Task IsFaulted: True
' Task Inner Exception: Error-First Task
' Task Inner Exception: Error-Second Task
' Task Inner Exception: Error-Third Task