[Swift] 에러 핸들링_do-catch? try?

호랭이·2021년 11월 17일
0

🍎 Swift

목록 보기
3/13

에러핸들링

Error Handling - The Swift Programming Language (Swift 5.5)

Throwing Functions를 이용한 에러 전파

  • 에러 전파

    함수 내에서 에러가 발생하여 정상적인 실행 흐름을 계속할 수 없을 수도 있음을 throw를 사용하여 나타낸다. 에러가 발생하는 경우에 throw명령문을 통해 에러를 던진다. throw 키워드를 사용한 함수만 에러를 전파할 수 있으며, throw하지 않는 함수 내에서 발생한 모든 오류는 함수 내에서 처리되어야 한다.

  • throwing funtion

    해당 함수 내에서 다른 함수 호출 시 에러가 발생할 수 있음을 나타내려면 함수 선언 시 매개변수 뒤에 throws 키워드를 작성한다. throws가 표시되어 있는 함수를 throwing function이라고 부른다.
    throwing function내에서 에러를 발생시킬 수 있는 코드를 호출하는 부분 앞에 try 키워드를 작성한다. throw된 에러는 throwing function 내에서 throw가 선언된 함수가 호출되는 지점까지 전파된다.


do-catch문을 사용한 에러 처리

do절의 코드에서 에러가 발생하면 catch 중 어느 것이 에러를 처리할 수 있는지 결정한다.

do {
    try expression
    statements
} catch pattern 1 {
    statements
} catch pattern 2 where condition {
    statements
} catch pattern 3, pattern 4 where condition {
    statements
} catch {
    statements
}

에러가 발생하면 즉시 catch로 이동하여 어떤 동작을 실행할지 결정한다. 일치하는 패턴이 없으면 에러가 마지막 catch에 의해서 잡히고 errer 상수에 바인딩된다. 에러가 발생하지 않는다면 do의 나머지 부분이 실행된다.
어떤 catch문도 에러를 처리하지 않으면 오류가 함수 바깥 범위로 전파된다. 에러가 처리되지 않고 최상위 범퍼로 전파되면 런타임 오류가 발생한다.

아래의 코드에서 nourish 함수를 호출하기 위해서 do catch문을 사용한다. nourish 함수 내에서 catch로 명시된 에러가 발생한다면 해당 에러처리를 하고, 그 밖의 에러가 발생한다면 nourish 함수를 호출하면서 작성한 catch 부분에서 기타 에러를 처리한다.

func nourish(with item: String) throws {
    do {
        try vendingMachine.vend(itemNamed: item)
    } catch is VendingMachineError {
        print("Couldn't buy that from the vending machine.")
    }
}

do {
    try nourish(with: "Beet-Flavored Chips")
} catch {
    print("Unexpected non-vending-machine-related error: \\(error)")
}
// Prints "Couldn't buy that from the vending machine."

관련된 여러가지 에러를 처리하기 위해서 catch 뒤에 쉼표로 구분하여 나열할 수도 있다.

func eat(item: String) throws {
    do {
        try vendingMachine.vend(itemNamed: item)
    } catch VendingMachineError.invalidSelection, VendingMachineError.insufficientFunds, VendingMachineError.outOfStock {
        print("Invalid selection, out of stock, or not enough money.")
    }
}

try?를 사용하여 에러를 옵셔널값으로 변환

try?를 사용한 코드에 에러가 발생하면 nil값을 반환한다.

아래의 코드에서 상수 x, y 는 같은 값과 동작이 같다.

func someThrowingFunction() throws -> Int {
    // ...
}

let x = try? someThrowingFunction()

let y: Int?
do {
    y = try someThrowingFunction()
} catch {
    y = nil
}

try?는 모든 오류를 동일한 방식으로 처리하려는 경우 간결한 코드를 작성할 수 있다.
아래의 코드에서는 함수에 대한 접근이 실패하면 모두 nil을 반환한다.

func fetchData() -> Data? {
    if let data = try? fetchDataFromDisk() { return data }
    if let data = try? fetchDataFromServer() { return data }
    return nil
}

에러 전파 비활성화

함수나 메소드가 에러를 발생시키지 않을 것이라 확신하는 경우 try! 를 사용하여 에러 전파를 비활성화한다.

loadmage(atPath:) 함수는 주어진 경로에서 이미지 리소스를 로드하거나 로드할 수 없는 경우 에러를 발생시킨다. 이 경우 이미지가 애플리케이션과 함께 제공되기 때문에 런타임에 오류가 발생하지 않을 것이라 확신할 수 있기 때문에 이 함수를 사용할 때 에러 전파 비활성화 방법을 많이 사용한다.

profile
삐약

0개의 댓글