Swift: Error Handling / 오류처리

Wooyo·2023년 10월 24일
0
post-thumbnail

1. Error Handling

  • Error 프로토콜을 준수
  • 주로 열거형을 통해서 오류를 표현
enum ErrorName: Error {
	case Error1
    case Error2
    case Error3
}

2. 에러 구현 예

enum VendingMachineError: Error {
    case invalidInput
    case insufficientFunds(moneyNeeded: Int)
    case outOfStock
}

3. 함수에서 오류 던지기

  • throws를 사용하여 오류를 내포하는 함수임을 표시
class VendingMachine {
    let itemPrice: Int = 100
    var itemCount: Int = 5
    var deposited: Int = 0
    // 돈 받기 메서드
    func receiveMoney(_ money: Int) throws {
        // 입력한 돈이 0이하면 오류 발생
        guard money > 0 else {
            throw VendingMachineError.invalidInput
        }
        // 오류가 없으면 정상처리
        self.deposited += money
        print("\(money)원 받음")
    }
    // 물건 팔기 메서드
    func vend(numberOfItems numberOfItemsToVend: Int) throws -> String {
        // 원하는 아이템의 수량이 잘못 입력되었으면 오류
        guard numberOfItemsToVend > 0 else {
            throw VendingMachineError.invalidInput
        }
        // 구매하려는 수량보다 미리 넣어둔 돈이 적으면 오류
        guard numberOfItemsToVend * itemPrice <= deposited else {
            let moneyNeeded: Int
            moneyNeeded = numberOfItemsToVend * itemPrice - deposited
            throw VendingMachineError.insufficientFunds(moneyNeeded: moneyNeeded)
        }
        // 구매하려는 수량보다 요구하는 수량이 많으면 오류
        guard itemCount >= numberOfItemsToVend else {
            throw VendingMachineError.outOfStock
        }
        // 오류가 없으면 정상처리
        let totalPrice = numberOfItemsToVend * itemPrice
        self.deposited -= totalPrice
        self.itemCount -= numberOfItemsToVend
        return "\(numberOfItemsToVend)개 제공함"
    }
}

// 자판기 인스턴스
let machine: VendingMachine = VendingMachine()
// 판매 결과를 전달받을 변수
var result: String?

4. 오류처리

  • 오류발생 여지가 있는 throws 메서드는 try 를 사용하여 호출

5. do - catch

  • 가장 기본적인 방법
do {
    try machine.receiveMoney(0)
} catch VendingMachineError.invalidInput {
    print("입력이 잘못되었습니다")
} catch VendingMachineError.insufficientFunds(let moneyNeeded) {
    print("\(moneyNeeded)원이 부족합니다")
} catch VendingMachineError.outOfStock {
    print("수량이 부족합니다")
} 
// 입력이 잘못되었습니다
  • 하나의 catch 블럭에서 switch 문 사용
do {
    try machine.receiveMoney(300)
} catch /*(let error)*/ {
    switch error {
    case VendingMachineError.invalidInput:
        print("입력이 잘못되었습니다")
    case VendingMachineError.insufficientFunds(let moneyNeeded):
        print("\(moneyNeeded)원이 부족합니다")
    case VendingMachineError.outOfStock:
        print("수량이 부족합니다")
    default:
        print("알수없는 오류 \(error)")
    }
} 
// 300원 받음
  • 케이스 별 오류처리 필요 없는 경우
do {
    result = try machine.vend(numberOfItems: 4)
} catch {
    print(error)
} 
// insufficientFunds(100)

// 혹은

do {
    result = try machine.vend(numberOfItems: 4)
}

6. try?

  • 별도의 오류처리 결과를 받지 않고 오류가 발생시 결과값을 nil로 받음
  • 정상동작 후 옵셔널 타입으로 정상 반환값을 돌려 받음
result = try? machine.vend(numberOfItems: 2)
result // Optional("2개 제공함")
result = try? machine.vend(numberOfItems: 2)
result // nil

7. try!

  • 오류가 발생하지 않을 것이라는 확신을 가질때 정상동작 후 결과값 반환
  • 오류 발생시 런타임 오류 발생하여 앱 중지
result = try! machine.vend(numberOfItems: 2)
result // Optional("2개 제공함")
result = try! machine.vend(numberOfItems: 2) // 런타임 오류 발생
profile
Wooyo의 개발 블로그

0개의 댓글