에러 정의

  • Swift의 에러는 Error 프로토콜을 준수하는 타입의 값으로 나타냄.
    • 이 프로토콜로 우리는 에러를 처리하는 데 사용할 수 있다! 라고 알림.
  • 커스텀 에러를 정의하고 싶다면 Error 프로토콜 채택 필요
enum MyError: Error {
    case customError1
    case customError2
}


예시를 통해 throw, try, do-catch를 이해해 보자.

사용할 예시는 은행 계좌와 관련된 로직

  • 거래가 불가능한 계좌이거나, 잔액이 부족한 상황을 핸들링할 수 있는 에러를 정의하고 처리해 보자.


에러 던지기 - Throwing

  • 에러가 발생할 수 있는 함수, 메서드, 초기화 구문에서는 파라미터 뒤에 throws 키워드 작성
  • 에러 상황에서는 throw를 사용하여 에러를 던지기.

  1. 에러 정의
enum AccountError: Error {
    case accountInactive
    case insufficient
}
  1. 계좌 클래스 생성
class BankAccount {
    var balance: Double
    var isActive: Bool

    init(initialBalance: Double, isActive: Bool) {
        self.balance = initialBalance
        self.isActive = isActive
    }

    // 인출하는 메소드
    func withdraw(amount: Double) throws {
        guard isActive else {
            throw AccountError.accountInactive // 던지기!
        }

        guard balance >= amount else {
            throw AccountError.insufficient // 던지기!
        }

        balance -= amount
        print("Withdrew \(amount). Remaining balance is \(balance).")
    }
}

에러 처리 - Do-Catch

  • do절에서 에러가 발생할 수 있는 함수 등을 호출
    • 에러가 발생할 수 있는 함수 등을 호출할 때는 try 키워드를 작성해야 함.

에러가 발생할 수 있지만 try해 볼게!

  • catch 절에서 어떤 에러인지를 결정하고 처리
let myAccount = BankAccount(initialBalance: 1000, isActive: true) 

do {
    try myAccount.withdraw(amount: 50000)
} catch AccountError.accountInactive {
    print("거래가 불가능한 계좌입니다." )
} catch AccountError.insufficient {
    print("잔액이 부족합니다.")
}

// 출력: 잔액이 부족합니다.

try

  • try / try? / try!
  • 앞서 말했던 것처럼 에러가 발생할 수 있는 함수를 호출할 때 사용

try

  • do-catch문과 함께 사용
  1. 정상적으로 동작할 때
let myAccount = BankAccount(initialBalance: 1000, isActive: true)
try myAccount.withdraw(amount: 100)

// Withdrew 100.0. Remaining balance is 900.0.
  1. 에러가 발생했을 때
let myAccount = BankAccount(initialBalance: 1000, isActive: true)
try myAccount.withdraw(amount: 5000)

// Playground execution terminated: An error was thrown and was not caught:

에러 처리를 해 주지 않았기 때문에, 에러가 처리되지 않았다는 에러가 발생한다.
따라서 do-catch문을 사용하거나,try? 혹은 try!를 사용해야 한다.

try?

  • 에러를 옵셔널 값으로 변환하여 처리
    • 에러가 발생하면 nil로 처리된다.
let myAccount = BankAccount(initialBalance: 1000, isActive: true)
try? myAccount.withdraw(amount: 5000) // nil

try!

  • 실제로 에러가 발생하지 않는 로직이라는 것을 보장할 수 있을 때 사용
  • 대신 에러가 발생한다면 크래쉬 발생
try! myAccount.withdraw(amount: 5000)

fatalError(_:file:line:)

  • message를 출력하고 즉시 실행 중지
  • 말그대로 치명적인 에러일 때
  • 즉시 실행이 중지되기 때문에 프로그램에 안정성에 도움이 되지 않는다. 실제로 운영되는 서비스에서는 유저에게 오류를 알리고 그에 맞는 처리를 할 필요가 있음.

0개의 댓글

Powered by GraphCDN, the GraphQL CDN