大器晩成

에러 처리 (Error Handling) 본문

iOS/Swift 문법

에러 처리 (Error Handling)

zerobugpark 2025. 3. 3. 19:40

 

에러 던지기

  • 함수나 메서드는 오류 객체를 외부로 던질 수 있다는 것을 컴파일러에 알려주기 위해 정의 구문을 작성할 때 throws 키워드를 추가합니다.
func canThrowErrors() throws -> String

func cannotThrowErrors() -> String
  • 에러가 발생할 수 있는 함수, 메서드, 또는 초기화 구문을 나타내기 위해 함수의 선언 중 파라미터 뒤에 throws 키워드를 작성합니다. throws로 표시된 함수는 던지기 함수 라고 합니다. 함수에 반환 타입이 지정되어 있으면 throws 키워드는 반환 화살표 (->) 전에 작성합니다.

 

 

에러의 처리 과정

1. 에러의 정의 (에러 프로토콜을 채택해야 함)

enum PayslipError: Error {
    case tooMany
    case tooSmall
}

 

 

2. 에러가 발생할 수 있는 함수에 대한 정의

func getPayslip(money: Int) throws -> String {
    
    if money >= 3_000_000 && money <= 4_000_000 {
        return "이번달은 입에 일주일에 치킨을 2번 먹을 수 있어요"
    } else if money < 3_000_000 {
        throw PayslipError.tooSmall
        
    } else {
        throw PayslipError.tooMany
    }
}

 

3. Do-Catch 사용하여 에러 처리 (Handling Errors Using 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#>
}
  • do 구문은 오류가 발생하지 않는 상황에서 실행할 구문이 작성됩니다.
  • 컴파일러는 do 구문 내부에 작성된 순서대로. 코드를 실행하다가 try함수 호출에서 오류가 던져지면 이를 catch구문으로 전달합니다.
  • catch 구문은 스위치 구문에서의 Case처럼 오류 타입을 각각 지정하여 작성할 수 있습니다.
  • where 절을 추가해서, 매칭시킬 에러 패턴에 조건을 추가할 수 있습니다.
  • 패턴을 작성하지 않을 경우 마지막 catch는 switch문의 default처럼 동작합니다.
  • catch구문 내에는 error라는 지역 상수가 있습니다. (throw가 error로 바인딩됨)

 

에러를 처리하는 3가지 방법 (try, try?, try!)

 

1. 정식으로 처리 try - do - catch

//1) 정식으로 처리

do {
    // 정상적인 경우의 처리 상황
    var msg = try getPayslip(money: 1_000_000) // 리턴값이 있을 때
    //try getPayslip(money: 1_000_000) // 리턴값이 없을 때
    print(msg)
    
} catch PayslipError.tooMany { 
    print("상여금이 나왔나요?")
} catch PayslipError.tooSmall {
    print("월급이 잘못찍혔는데요?...")
}


do {
    var msg = try getPayslip(money: 1_000_000) // 리턴값이 있을 때
} catch { // error를 상수 제공
    print(error)
    
    if let result = error as? PayslipError {
        switch result {
        case .tooMany:
            print("상여금이 나왔나요?")
        case .tooSmall:
            print("월급이 잘못찍혔는데요?...")
        }
    }
    
}

// 스위프트 5.3 에러를 ,(콤마로 나열 가능)
do {
    var msg = try getPayslip(money: 1_000_000)
    print(msg)
    
} catch PayslipError.tooMany, PayslipError.tooSmall  {
    print("에러 한번에 처리")
}

 

2. try?(Optional try) - 옵셔널  타입으로 리턴

let msg = try? getPayslip(money: 2_000_000)
  • 정상인 경우 원래 리턴타입으로 반환합니다.
  • 에러가 발생하면 nil이 반환됩니다.

3. try! (Forced try)

let msg2 = try! getPayslip(money: 3_000_000)
  • 에러가 날 수 없는 경우에만 사용이 가능합니다.
  • 정상인 경우 원래 리턴타입으로 반환합니다.
  • 에러가 발생하면 런타임에러가 발생합니다.
728x90