🔥 오류 처리

468자
7분

프로그램을 작성하다 보면 실행 중에 오류가 발생할 수 있습니다. 이런 오류 상황에 적절히 대응하기 위해 Swift는 오류 처리(Error Handling) 기능을 제공하고 있어요.

옵셔널(Optional)은 값의 존재 여부로 성공과 실패를 표현하는 반면, 오류 처리는 실패의 근본 원인을 파악하고 필요한 경우 오류를 프로그램의 다른 부분으로 전파할 수 있게 해준답니다.

함수가 오류 상황을 만나면 오류를 던집니다(throw). 그러면 함수를 호출한 쪽에서 오류를 잡아내어(catch) 적절히 대응할 수 있죠.

func canThrowAnError() throws {
    // 이 함수는 오류를 던질 수도 있고 던지지 않을 수도 있어요
}
swift

함수가 오류를 던질 수 있음을 나타내려면 함수 선언부에 throws 키워드를 포함시키면 됩니다. 오류를 던질 수 있는 함수를 호출할 때는 try 키워드를 표현식 앞에 붙이면 돼요.

Swift는 오류가 catch 절에 의해 처리될 때까지 현재 범위에서 자동으로 오류를 전파합니다.

do {
    try canThrowAnError()
    // 오류가 던져지지 않았어요
} catch {
    // 오류가 던져졌네요
}
swift

do 문은 새로운 포함 범위를 생성하며, 이를 통해 오류를 하나 이상의 catch 절로 전파할 수 있어요.

다음은 오류 처리를 사용하여 다양한 오류 상황에 대응하는 예시 코드입니다.

func makeASandwich() throws {
    // ...
}
 
do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}
swift

이 예시에서 makeASandwich() 함수는 깨끗한 접시가 없거나 재료가 부족한 경우 오류를 던집니다. makeASandwich()가 오류를 던질 수 있으므로 함수 호출을 try 표현식으로 감싸줍니다. 함수 호출을 do 문으로 감싸면 던져진 모든 오류는 제공된 catch 절로 전파되죠.

오류가 던져지지 않으면 eatASandwich() 함수를 호출합니다. 만약 SandwichError.outOfCleanDishes 케이스와 일치하는 오류가 던져지면 washDishes() 함수를 호출하고요. 그리고 SandwichError.missingIngredients 케이스와 일치하는 오류가 던져지면 catch 패턴에 의해 포착된 [String] 값과 함께 buyGroceries(_:) 함수를 호출합니다.

오류 던지기, 잡아내기, 전파하기에 대한 더 자세한 내용은 Error Handling에서 다루고 있으니 참고하길 바랍니다.

오류 처리를 잘 활용하면 예기치 않은 상황에서도 프로그램이 안정적으로 동작하도록 만들 수 있습니다. 어떤 함수에서 발생 가능한 오류를 미리 정의하고, 해당 오류가 발생했을 때 취해야 할 행동을 catch 블록에 명시해 두는 거예요.

이를 통해 문제 상황을 식별하고 복구하는 로직을 깔끔하게 분리할 수 있죠. 예를 들어 네트워크 요청 함수에서 요청 실패 오류를 던지면, 호출부에서는 재시도를 하거나 사용자에게 알림을 표시하는 식으로 대응할 수 있답니다.

이런 에러 처리 흐름을 간단히 도식화하면 다음과 같습니다.

lecture image

이 다이어그램은 에러 처리의 기본 흐름을 보여줍니다.

  1. 함수가 에러를 던질 수 있음을 throws 키워드로 선언합니다.
  2. do 블록 내에서 에러를 던질 수 있는 함수를 try로 호출합니다.
  3. 에러가 발생하지 않으면 try 이후의 코드가 실행됩니다.
  4. 에러가 발생하면 catch 블록으로 점프하여 에러를 처리합니다.

이렇게 에러 처리 흐름을 시각화하면 코드의 동작을 한 눈에 파악할 수 있어요. 에러가 발생할 수 있는 부분을 명확히 알 수 있고, 에러 발생 시 어떤 동작이 이루어지는지 쉽게 이해할 수 있죠.

실제 코드에서는 다양한 에러 타입과 catch 블록을 사용하여 더욱 세밀한 에러 처리를 할 수 있습니다. 하지만 위 다이어그램은 에러 처리의 기본 개념을 잘 나타내 주고 있어요.

에러 처리는 견고한 애플리케이션을 만드는 데 필수적인 요소입니다. 예상치 못한 상황에 대응하고 사용자에게 적절한 피드백을 제공할 수 있게 해주죠. 위 다이어그램을 참고하여 에러 처리 흐름을 이해하고, 여러분의 코드에 적용해 보세요!