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 adalah Exception, 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:

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

Lihat juga