SoFunction
Updated on 2025-04-06

Description of how to deal with Swift Error

Error Type

1. Common errors in the development process

  • Syntax error (compilation error)
  • Logical error
  • Runtime errors (may cause crashes, usually called exceptions), which is also the focus of our discussion today.

Custom errors

1. Swift can customize the runtime error message through the Error protocol

enum SomeError: Error {
    case illegalArg(String)
    case outOfBounds(Int, Int)
    case outOfMemory
}

2. The function throws a custom Error through throw. The function that may throw an Error must be added with a throws declaration.

func divide(_ num1: Int, _ num2: Int) throws -> Int {
    if num2 == 0 {
        throw ("0 cannot be used as a divisor")
    }
    return num1 / num2
}

3. You need to use a try to call a function that may throw an Error

4. You can use do-catch to catch Error

func test() {
    do {
        try divide(20, 0)
    } catch let (msg) {
        print("Parameter exception:", msg)
    } catch let (size, index) {
        print("Subscript crosses the line:", "size = \(size), index = \(index)")
    } catch  {
        print("Memory overflow")
    } catch {
        print("Other errors")
    }
}

5. After Error is thrown, the code that will stop running until the end of the scope of the try sentence stops running.

Handle Error

1. Two ways to deal with Error

a. Catch Error through do-catch

b. Do not catch the Error, add throws declaration to the current function, and the Error will be automatically thrown to the upper function

func test() throws {
    print(try divide(200, 0))
}

If the top-level function (main function) still does not catch the Error, the program will terminate

Here are several ways to deal with errors:

func test() throws {
    do {
        print(try divide(200, 0))
    } catch let error as SomeError {
        print(error)
    }
}
func test() throws {
    do {
        print(try divide(200, 0))
    } catch is SomeError {
        print("SomeError")
    }
}
do {
    try divide(20, 0)
} catch let error {
    switch error {
    case let (msg):
        print("Parameter exception:", msg)
    default:
        print("Other exceptions")
    }
}

Let's summarize two ways to deal with Error using an example:

override func viewWillAppear(_ animated: Bool) {
    (animated)
    try test0()
}
func test0() throws -> Void {
    try test1()
}
func test1() throws -> Void {
    try test2()
}
func test2() throws -> Void {
    do {
        print(try divide(200, 0))
    } catch is SomeError {
        print("This is SomeError")
    }
}

try? and try!

1. You can use try?, try! to call a function that may throw an Error, so that you don't have to deal with Error.

func test() -> Void {
    print("1")
    var result1 = try? divide(20, 10) // Optional(2), Int?
    var result2 = try? divide(20, 0) // nil
    var result3 = try! divide(20, 10) // 2, Int
    print("2")
}

2. a and b are equivalent

var a = try? divide(20, 0)
var b: Int?
do {
    b = try divide(20, 0)
} catch {
    b = nil
}

rethrows

1. rethrows indicates that the function itself will not throw an error, but call the closure parameter to throw an error, then it will throw the error upwards.

func exec(_ fn: (Int, Int) throws -> Int, _ num1: Int, _ num2: Int) rethrows -> Void {
    print(try fn(num1, num2))
}

defer

1. Defer statement: used to define the code that must be executed before leaving the code block in any way (missing errors, return, etc.)

Defer statement will be delayed until the end of the current scope

func open(_ filename: String) -> Int {
    print("open")
    return 1
}
func close(_ file: Int) -> Void {
    print("close")
}
func processFile(_ filename: String) throws -> Void {
    let file = open(filename)
    defer {
        close(file)
    }
    try divide(20, 0)
}

2. The execution order of the defer statement is opposite to the definition order.

func fn1() -> Void {
    print("fn1")
}
func fn2() -> Void {
    print("fn2")
}
func testDefer() -> Void {
    defer {
        fn1()
    }
    defer {
        fn2()
    }
} //fn2 fn1

This is the end of this article about the description of how to deal with Swift Error. For more related Swift Error content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!