Do-Catch: apa itu, konstruksi dan penanganan error di Swift

Penulis: IT Sectr Diterbitkan: 2026-05-26 Waktu membaca: 8 mnt

Do-Catch — konstruksi bahasa Swift untuk penanganan error yang menangkap pengecualian yang dilemparkan melalui throw dan menjalankan blok kode yang sesuai. Berbeda dengan try-catch tradisional di bahasa lain, Swift memerlukan penandaan eksplisit fungsi yang dapat melempar error dengan modifier throws. Menurut Swift.org, 2026, Do-Catch adalah mekanisme utama penanganan error di Swift yang memastikan keamanan di tingkat tipe.

Poin Utama

  • Do-Catch — konstruksi Swift yang menangkap error dari blok dengan try dan throw.
  • throws — penanda fungsi yang menandakan bahwa fungsi dapat melempar error.
  • try — kata kunci untuk memanggil fungsi throwing di dalam blok do.
  • catch — blok penanganan error dengan kemungkinan pencocokan berdasarkan tipe.
  • try? dan try! — bentuk alternatif yang mengubah error menjadi nil atau menyebabkan crash.

Apa itu Do-Catch?

Do-Catch — adalah konstruksi di Swift yang terdiri dari blok do, di dalamnya kode yang dapat melempar error dijalankan, dan satu atau lebih blok catch yang menangani error tersebut. Blok do berisi pemanggilan fungsi throwing yang ditandai dengan try, dan blok catch mencocokkan error berdasarkan tipe.

Swift mengimplementasikan model penanganan error terstruktur, berbeda dari pengecualian di Objective-C. Di sini error bukanlah exception dengan penguraian stack, melainkan nilai yang sesuai dengan protokol Error. Melempar error melalui throw mentransfer kontrol ke blok catch terdekat tanpa biaya penguraian stack.

Fitur kunci Swift — keeksplisitan penanganan. Kompiler tidak mengizinkan pemanggilan fungsi throwing tanpa try, do-catch atau mekanisme alternatif (try?, try!). Ini menghilangkan situasi di mana error tidak terdeteksi.

Model error di Swift: protokol Error dan fungsi throwing

Dasar penanganan error di Swift adalah protokol Error. Tipe apa pun yang sesuai dengan protokol ini dapat dilemparkan melalui throw. Biasanya error didefinisikan sebagai enum dengan konfirmasi Error.

Protokol Error

Error — protokol kosong (penanda). Tidak memerlukan implementasi metode, hanya konfirmasi kesesuaian. Kompiler Swift menggunakan Error untuk pemeriksaan statis: fungsi dengan throws hanya dapat melempar nilai yang sesuai dengan Error.

Fungsi throwing

Fungsi yang ditandai dengan throws harus dipanggil dengan try. Jika di dalam fungsi tersebut terjadi throw, kontrol ditransfer ke do-catch pemanggil. Jika error tidak ditangani di mana pun dalam rantai pemanggilan, error akan diteruskan ke tingkat yang lebih tinggi.

swift
enum FileError: Error {
    case notFound
    case permissionDenied
    case corrupted(String)
}

func readFile(path: String) throws -> String {
    guard FileManager.default.fileExists(atPath: path) else {
        throw FileError.notFound
    }
    return try String(contentsOfFile: path)
}

Propagasi error rethrows

rethrows — modifier untuk fungsi yang menerima throwing-closure sebagai parameter. Jika closure yang diberikan tidak melempar error, fungsi rethrows dapat dipanggil tanpa try. Ini memungkinkan penulisan fungsi tingkat tinggi generik yang kompatibel dengan closure throwing dan non-throwing.

Sintaks Do-Catch: beberapa blok catch

Swift mendukung banyak blok catch dengan pencocokan berdasarkan tipe error. Ini mirip dengan when di Kotlin atau switch berdasarkan tipe: catch pertama yang cocok dijalankan, sisanya dilewati.

Pencocokan berdasarkan tipe

Setiap blok catch dapat berisi pola pencocokan dengan tipe error tertentu. Swift memeriksa blok secara berurutan, jadi tipe yang lebih spesifik harus ditempatkan sebelum tipe umum. Jika tidak ada pola yang cocok, blok catch tanpa pola akan dijalankan.

Penanganan beberapa tipe

Keamanan tipe Do-Catch memungkinkan penanganan setiap error secara terpisah atau menggabungkan beberapa tipe dalam satu blok melalui koma di pattern-matching. Ini menghilangkan rantai if-else yang rumit yang menjadi ciri khas Objective-C, di mana analisis error dilakukan melalui kode pengembalian atau NSError dengan pemeriksaan domain dan code.

Swift juga mendukung catch where — pencocokan dengan kondisi tambahan. Misalnya, error dapat difilter berdasarkan kode atau teks tertentu: catch URLError where error.code == .notConnectedToInternet. Ini mengurangi jumlah blok catch sambil mempertahankan presisi penanganan.

Untuk debugging fungsi throwing, Swift menyediakan perbedaan antara error dan pengecualian. Error Swift — adalah nilai yang dikembalikan yang tidak memerlukan penguraian stack. Pengecualian Objective-C (@try/@catch) bekerja di tingkat runtime dan hanya digunakan untuk kegagalan fatal. Do-Catch menangani tepat error, bukan pengecualian, yang membuatnya dapat diprediksi dan efisien.

Saat mengembangkan pustaka dan SDK, penting untuk diingat bahwa fungsi throwing adalah bagian dari kontrak publik. Tipe error tidak ditentukan dalam tanda tangan, oleh karena itu dokumentasikan error apa yang dapat dilemparkan fungsi dalam komentar atau melalui enum mirip Result. Ini membantu pengguna API menulis blok catch yang benar tanpa perlu melihat implementasi.

Dalam konteks pemrograman asinkron, Do-Catch dengan async/await memecahkan masalah callback hell. Sebelumnya di Swift, penanganan error dalam kode asinkron memerlukan closure bersarang dengan pemeriksaan Error? di completion handler. Dengan async/await dan Do-Catch, kode throwing asinkron terlihat seperti kode sinkron, yang menyederhanakan pembacaan dan pemeliharaan rantai permintaan kompleks dengan penanganan error di setiap langkah.

swift
do {
    let content = try readFile(path: "/data/config.json")
    process(content)
} catch FileError.notFound {
    createDefaultConfig()
} catch FileError.permissionDenied {
    requestAccess()
} catch FileError.corrupted(let detail) {
    logCorruption(detail)
} catch {
    print("Error tidak dikenal: \(error)")
}

Varian try: try, try?, try! dan kapan menggunakannya

Swift menawarkan tiga varian pemanggilan fungsi throwing: try, try? dan try!. Setiap varian memecahkan tugas tertentu dan memiliki keterbatasannya sendiri.

try — pemanggilan standar

try digunakan di dalam blok do, dan error ditangani di catch. Ini adalah cara utama pemanggilan fungsi throwing. Kompiler mensyaratkan try berada dalam konteks di mana error dapat ditangkap.

try? — konversi ke Optional

try? mengonversi hasil fungsi throwing menjadi Optional. Jika fungsi melempar error, try? mengembalikan nil, jika tidak — Optional dengan nilai berhasil. Berguna untuk pemanggilan di mana error dapat diabaikan tetapi indikator keberhasilan diperlukan.

try! — eksekusi paksa

try! menekan penanganan error. Jika fungsi throwing melempar error, aplikasi akan berakhir dengan error runtime. Gunakan try! hanya ketika Anda benar-benar yakin bahwa error tidak mungkin terjadi — misalnya, saat memuat resource bawaan.

swift
// try? — mengabaikan error, mendapatkan nil saat gagal
if let data = try? Data(contentsOf: url) {
    processData(data)
}

// try! — hanya jika error dijamin tidak mungkin
let bundled = try! String(contentsOfFile: "Assets/default.txt")

// try — opsi standar di do-catch
do {
    let result = try performNetworkRequest()
    updateUI(result)
} catch {
    showError(error)
}

Do-Catch di pengembangan iOS: contoh praktis

Do-Catch secara aktif digunakan dalam pengembangan iOS untuk bekerja dengan API sistem. Mari kita lihat skenario tipikal: bekerja dengan sistem file, Core Data dan permintaan jaringan.

Sistem file

Banyak metode FileManager bersifat throwing. Do-Catch memungkinkan penanganan yang tepat atas ketiadaan file, resource yang sibuk, atau kurangnya izin.

Permintaan jaringan dengan Codable

Parsing JSON melalui JSONDecoder — operasi throwing. Do-Catch menangkap error decoding dan kegagalan jaringan secara terpisah, memberikan teks error yang tepat kepada pengguna.

swift
struct User: Codable {
    let id: Int
    let name: String
}

func fetchUser(id: Int) async throws -> User {
    let url = URL(string: "https://api.example.com/users/\(id)")!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// Pemanggilan dengan penanganan
do {
    let user = try await fetchUser(id: 42)
    showUser(user)
} catch let error as URLError {
    showNetworkAlert(error)
} catch let error as DecodingError {
    showParseError(error)
} catch {
    showGenericError(error)
}

Kesalahan umum saat bekerja dengan Do-Catch

Pengembang, terutama yang beralih dari bahasa lain, sering melakukan kesalahan khas saat menggunakan Do-Catch. Mari kita lihat yang paling umum.

  • Try terlupakan — pemanggilan fungsi throwing tanpa try menyebabkan error kompilasi. Swift tidak mengizinkan pengabaian error secara implisit.
  • Catch kosong — blok catch tanpa penanganan menyembunyikan error. Selalu log atau tangani error, bahkan jika tampaknya tidak mungkin.
  • Catch tanpa pencocokan — satu catch umum untuk semua error menghilangkan keuntungan keamanan tipe. Pisahkan penanganan berdasarkan tipe melalui beberapa blok.
  • Penggunaan try! yang berlebihan — try! dalam kode produksi adalah sumber crash tak terduga. Gunakan hanya untuk resource bawaan atau pengujian.

Pertanyaan yang Sering Diajukan

Apa perbedaan Do-Catch di Swift dengan try-catch di bahasa lain?

Di Swift, error adalah nilai yang sesuai dengan protokol Error, bukan exception dengan penguraian stack. Fungsi throwing harus ditandai secara eksplisit dengan throws, dan kompiler mensyaratkan try saat pemanggilan — ini menghilangkan error yang tidak tertangani pada tahap kompilasi.

Bisakah Do-Catch digunakan dengan async/await?

Ya, fungsi async juga bisa throws, dan do-catch bekerja untuk mereka. Pemanggilan fungsi async throwing memerlukan try await di dalam blok do. Ini adalah cara standar penanganan error dalam kode asinkron Swift.

Bagaimana cara menangani error tanpa do-catch?

Ada alternatif: try? mengubah error menjadi nil, try! menyebabkan crash saat error, dan rethrows memungkinkan propagasi error dari closure. Do-catch tetap menjadi cara utama penanganan eksplisit.

Bisakah satu fungsi melempar berbagai tipe error?

Swift tidak mengetik error yang dilemparkan — fungsi throwing apa pun dapat melempar tipe apa pun yang sesuai dengan Error. Pisahkan penanganan melalui pencocokan di catch dengan tipe error tertentu.

Apakah perlu membungkus semua error ke dalam tipe kustom sendiri?

Ya, ini praktik terbaik. Definisikan AppError sebagai enum dengan konfirmasi Error dan konversikan error sistem menjadi error domain. Ini menyatukan penanganan dan mengisolasi lapisan aplikasi dari detail sistem.

Kesimpulan

  • Do-Catch — konstruksi Swift untuk penanganan error dengan penandaan throws wajib pada fungsi dan try saat pemanggilan.
  • Error Swift — nilai yang sesuai dengan protokol Error, bukan pengecualian dengan penguraian stack, yang memberikan biaya nol saat tidak ada kegagalan.
  • Banyak catch memungkinkan penanganan berbagai tipe error secara terpisah dengan pattern-matching analog dengan switch.
  • try? mengubah error menjadi nil untuk skenario sederhana, try! — pemanggilan paksa dengan risiko crash, hanya digunakan untuk operasi yang dijamin berhasil.
  • Do-Catch dengan async/await — cara standar penanganan error dalam kode asinkron Swift menggunakan try await.
  • Hindari catch kosong dan penggunaan try! yang berlebihan — ini menyembunyikan error dan menyebabkan kegagalan tak terduga dalam produksi.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga