contents

에러처리, 예외처리(throws, throw, do-try-catch)

<aside> 🧨 프로그램 내에서 에러가 발생한 상황에 대해 대응하고 이를 복구하는 과정

</aside>

Q. 에러는 무엇인가?

A. Error 프로토콜을 따르는 타입의 값

Q. 예외 처리 왜 필요한가?

A. optional타입은 오류가 발생했을 때 오류에 대한 정보를 외부로 전달할 방법이 없다. 따라서 예외 처리를 통해서 오류를 처리하자!

에러 처리를 하기 위해선 세 가지 과정이 필요합니다.

  1. 오류의 종류 정의하기(옵션)

    enum NetworkError: Error {
    	case authErr
    	case pathErr
    	case serverErr
    }
    
    enum TestError: Error {
    	case notANumber
    	case invalidInput(testNum: Int)
    }
    
  2. 발생한 오류 던지기

  3. 던진 오류 처리하기

    try와 do-catch로 오류를 처리합니다.

    class Rate {
    	private func calculateRate(watched: Int, total: Int) throws -> Double {
        guard total != 0 else { throw TestError.notANumber }
        let result = Double(watched) / Double(total)
    
        return result
    	}
    }
    
    class AnotherClass {
    	private func test() {
    		let rate = try Rate().calculateRate(watched: 10, total: 0)
    	}
    }
    
    1. 오류를 발생시키는 메소드 앞에 try를 넣어줍니다.

      try : calculateRate가 오류를 발생시킬 수도 있지만, 한 번 시도해보겠다.

    2. do-catch문을 사용해서 오류를 처리해준다.

      • do-catch는 오류를 처리하는 가장 간단한 방법이다.
      • 오류를 정의하지 않아도 에러 출력이 가능
      • catch를 생략해도 무방
      • 케이스별로 처리하기 때문에 switch문으로도 쓸 수 있습니다.
      do {
      	let rate = try Rate().calculateRate(watched: 10, total: 0)
      } catch {
      	print(error)
      }
      
      class AnotherClass {
      	private func test() {
      		do {
      			let rate = try Rate().calculateRate(watched: 10, total: 0)
      		} catch TestError.notANumber {
      			print("0를 넣으면 inf가 생성됩니다.. 에러!")
      		} catch TestError.invalidInput(let testNumber) {
      			print("부적절한 숫자를 넣었습니다. \\(testNumber)")
      		}
      	}
      }
      
      enum TestError: Error, String {
      	case notANumber = "0를 넣으면 inf가 생성됩니다.. 에러!"
      	case invalidInput = "부적절한 숫자를 넣었습니다."
      }
      
      class AnotherClass {
      	private func test() {
      		do {
      			let rate = try Rate().calculateRate(watched: 10, total: 0)
      		} catch {
      				switch error {
      					case TestError.notANumber:
      						print(error.rawValue)
      					case TestError.invalidInput:
      						print(error.rawValue)
      				}
      		} 
      	}
      }
      

try? try!

기본적으로 사용하는 try는 성공하는 경우에 unwrapping된 값을 반환받게 됩니다.