Swift
[Swift] Error Handling
learner._.Kio
2021. 3. 16. 16:18
목차
- Error Handling
- do-catch Statements
- Optional Try
- defer Statements
- Result Type #1
- Result Type #2
Error Handling
Error 종류
Compile Time Error
- 문법과 관련
Runtime Error
- 프로그램이 실행되는 동안 발생. 문법이 아니더라도 device, resource 상태에 따라서 error가 발생할 수 도 있음.
Error Handling 선언
Throwing Function / Method
func name(parameters) throws -> ReturnType { statement }
Throwing Initializer
init(parameters) throws { statement }
Throwing Closure
{ (parameters) throws- > ReturnType in statements }
Error Handling 예시
enum DataParsingError: Error {
case invalidType
case invalidField
case missingRequiredField(String)
}
func parsing(data: [String: Any]) throws {
guard let _ = data["name"] else {
throw DataParsingError.missingRequiredField("name")
}
guard let _ = data["age"] as? Int else {
throw DataParsingError.invalidType
}
}
throws
로 선언했다고 해서 꼭throw
를 써야하는 건 아니다.- 오류가 있을 때만
throw
를 던지면 된다.
try Statements
// do-catch
try expression
// optional try, error가 발생할 경우 nil return
try? expression
// Forced try, error 발생할 경우 runtime error, 사용하지 않는 것이 좋음.
try! expression
try 예시
enum DataParsingError: Error {
case invalidType
case invalidField
case missingRequiredField(String)
}
func parsing(data: [String: Any]) throws {
guard let _ = data["name"] else {
throw DataParsingError.missingRequiredField("name")
}
guard let _ = data["age"] as? Int else {
throw DataParsingError.invalidType
}
}
try? parsing(data: [:]) // nil, crash 발생 X
Error를 처리하는 방법
Do-catch Statments
try Expression + Optional Binding
hand over
do-catch Statements
do-catch 선언
do {
try expression
statements
} catch pattern {
statement
} catch pattern where condition {
statement
}
do-catch 예시
enum DataParsingError: Error {
case invalidType
case invalidField
case missingRequiredField(String)
}
func parsing(data: [String: Any]) throws {
guard let _ = data["name"] else {
throw DataParsingError.missingRequiredField("name")
}
guard let _ = data["age"] as? Int else {
throw DataParsingError.invalidType
}
// Parsing
}
catch문을 작성할 때는 가장 까다로운 블럭부터 작성해야한다.
do { try parsing(data: [:]) } catch DataParsingError.invalidType { print("invalid type error") } catch { print("handle error") } // handle error
catch문의 순서를 바꿔도 compile error가 발생하지 않는다.
do { try parsing(data: ["name": ""]) } catch { print("handle error") // 항상 이 구문이 실행 } catch DataParsingError.invalidType { print("invalid type error") } // handle error
pattern이 생략된 catch 블럭은 항상 마지막에 작성해야 한다.
do { try parsing(data: ["name": ""]) } catch DataParsingError.invalidType { print("invalid type error") } catch { print("handle error") } // invalid type error
do 블럭에서 발생할 수 있는 모든 Error를 catch 블럭에서 처리해야한다.
func handleError() { do { try parsing(data: ["name": ""]) } catch DataParsingError.invalidType { print("invalid type error") } } // pattern이 생략된 catch 블럭 삭제하니 compile error
- 에러를 해결하는 방법
- 모든 Error를 처리하는 catch 블럭 구현
- handleError() 나머지 Error를 다른 코드로 던지도록 선언
func handleError() throws { do { try parsing(data: ["name": ""]) } catch DataParsingError.invalidType { print("invalid type error") } } // catch문 생략 가능 - 생략 시 try만 사용 가능 func handleError() throws { // do { try parsing(data: ["name": ""]) // } }
- 에러를 해결하는 방법
pattern이 없는 catch 블럭
func handleError() throws { do { try parsing(data: ["name": ""]) } catch /*나머지 모든 error 처리*/ { if let error = error as? DataParsingError { switch error { case .invalidType: print("invalid type") default: print("items: Any..") } } } }