Error Handling
- 오류 정의 정의/ throw / try do - catch까지 사용한 예‼️⁉️ throws를 하는 함수를 사용하려면 무조건 앞에 try를 붙혀주어야된다.
// enum형으로 error타입명 정의
enum DataError : Error { // Error 프로토콜을 구현한 것은 오류 타입으로 사용하라는 일종의 가독성 표시
case overSizeYear
case incorrectData(part: Int)
}
// 오류가 나는 조건을 throws와 함께 배치 -> throw 문 추가
func getNextYearAndThrows(paramYear: Int) throws -> Int {
guard paramYear <= 2020 else {
throw DataError.overSizeYear
}
guard paramYear >= 0 else {
throw DataError.incorrectData(part: paramYear)
}
return paramYear+1
}
// 실제로 응용프로그램에서 불러올 함수 -> try do catch 문 사용
func getNextYear(paramYear: Int) -> Int {
var year: Int = 0
do {
year = try getNextYearAndThrows(paramYear: paramYear)
} catch DataError.overSizeYear {
print("년도 초과해서 입력하였습니다")
} catch DataError.incorrectData(let part){
print("입력한 값이 \(part)이므로 오류입니다.")
} catch {
print("default error catch")
}
return year
}
let a = getNextYear(paramYear: -999) // 입력한 값이 -999이므로 오류입니다.
Localized error와 errordescription 사용하기
import Foundation
enum StockError: LocalizedError {
case noCorrespondingFruit
case notEnoughToMakeJuice
case notEnoughToChange
var errorDescription: String? {
switch self {
case .noCorrespondingFruit:
return "일치하는 과일이 없습니다."
case .notEnoughToMakeJuice:
return "재료가 모자라요."
case .notEnoughToChange:
return "더 이상 변경할 수 없어요."
}
}
}
func tryError(if x: Int) throws {
if x == 0 {
throw StockError.noCorrespondingFruit
} else if x == 1 {
throw StockError.notEnoughToMakeJuice
} else {
throw StockError.notEnoughToChange
}
}
func catchError(if x: Int) {
do {
try tryError(if: x)
} catch {
print(error.localizedDescription)
}
}
catchError(if: 0) // 일치하는 과일이 없습니다.
catchError(if: 1) // 재료가 모자라요.
catchError(if: 2) // 더 이상 변경할 수 없어요.
오류의 종류를 정의하기
- enum 형식으로 오류의 종류를 정의할 수 있다.
enum DataParsingError: Error {
case invalidType
case invalidField
case missingRequiredField(String)
}
오류를 던지기(throw)
- 만약 아래와 같은 코드를 작성했다고 하자
func parsing(data: [String: Any]) {
guard let _ = data["name"] else {
return
}
guard let _ = data["age"] as? Int else {
return
}
}
- 위의 코드는 else일 경우 에러가 나와 return을 하면서 끝내게 되는데 만약 else일 경우 미리 정의해 놓은 오류를 던지고 싶다면? 아래와 같이 throw와 throws를 코드에 넣어주면 된다.
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?
- 에러가 발생할 수 있는데 한번 실행해보는 것이다. ?의 경우 에러가 발생할 경우 nil을 리턴한다.
try? parsing(data: [:]) //nil
tyr!
- 에러가 발생하지 않을거라고 확신할 때만 사용을 한다.
Do- Catch
- 기본 꼴은 아래와 같다.
do {
try expression
statements
} catch pattern {
statements
} catch pattern where condition {
statements
}
- do 블록을 실행해서 만약 error가 나오게 되면 그 에러가 무엇이냐에 따라서 위에서 부터 아래로 확인해가며 catch 블록이 선택되어 실행이 된다.
do {
try parsing(data: [:])
} catch DataParsingError.invalidType {
print("invalid type error")
} catch {
print("handle error")
}
- 만약 pattern이 없을 경우, 아래와 같은 방식으로 error handling을 자주 해준다.
// 만약 pattern이 없을 경우 아래와 같은 방식으로 error handling을 자주한다.
func handleError() throws {
do {
try parsing(data: ["name":""])
} catch {
if let error = error as? DataParsingError {
switch error {
case .invalidType:
print("invalid type")
default:
print("handle error")
}
}
}
}
Defer
- 말그대로 해당 코드를 맨 마지막에 실행히시키는 것이다
- 함수를 종료하기 직전에 정리해야 하는 변수나 상수를 처리하는 용도
출처/참고 - https://babbab2.tistory.com/80
'Swift' 카테고리의 다른 글
[Swift] 값 타입, 참조 타입, let, var (0) | 2023.02.24 |
---|---|
[Swift] 함수 return에대한 고민 (0) | 2023.02.20 |
[Swift] 프로퍼티 옵저버 (0) | 2023.02.11 |
[Swift] 상속(Inheritance) (0) | 2023.02.11 |
[Swift] Lazy (지연 저장 프로퍼티) (0) | 2023.02.11 |