Menu
Coddy logo textTech

에러 전파하기

Coddy Swift 여정의 로직 및 흐름 섹션에 포함된 레슨 — 56개 중 47번째.

에러를 던지는 함수는 다른 에러를 던지는 함수를 호출할 수 있습니다. 에러는 수동으로 다시 던질 필요 없이 가장 가까운 do/catch로 자동으로 전파됩니다.

enum AuthError: Error { case badUser, badPass }

func loadUser(_ name: String) throws -> String {
    if name.isEmpty { throw AuthError.badUser }
    return name
}

func login(_ name: String, _ pass: String) throws -> String {
    let u = try loadUser(name)            // 에러를 전달함
    if pass.count < 4 { throw AuthError.badPass }
    return "hello \(u)"
}

do {
    print(try login("", "abcd"))
} catch AuthError.badUser {
    print("missing user")
} catch AuthError.badPass {
    print("weak password")
}

위에서 아래로 읽으세요: logintry를 사용하여 loadUser를 호출합니다. 만약 loadUser가 에러를 던지면, 에러는 login의 본문을 건너뛰고 외부의 catch에 도달합니다. 각 단계를 빠르게 실패하도록 작성하여 호출자가 어떻게 처리할지 결정하게 하세요.

challenge icon

챌린지

중급

두 개의 에러를 던지는 단계로 구성된 작은 파이프라인을 구축하세요.

두 가지 케이스를 가진 StepError: Error를 정의하세요: negative, tooBig.

parseSafe(_ s: String) throws -> Int를 정의하세요: 파싱된 정수가 0 미만이면 .negative를 던지고, 그렇지 않으면 정수를 반환합니다. (입력 파싱은 성공한다고 가정하며, 이는 다른 곳에서 처리되었다고 봅니다.)

capStrict(_ n: Int) throws -> Int를 정의하세요: n > 100이면 .tooBig을 던지고, 그렇지 않으면 n을 반환합니다.

parseSafe를 호출한 다음 capStrict를 호출하고, 발생하는 모든 에러를 전파하는 processStep(_ s: String) throws -> Int를 정의하세요.

쉼표로 구분된 문자열 리스트인 입력 한 줄을 읽습니다. 각 문자열에 대해 do/catch 문 안에서 processStep을 호출하고 한 줄씩 출력하세요:

  • 성공 시 ok: <n>
  • parseSafe가 에러를 던졌을 때 negative
  • capStrict가 에러를 던졌을 때 too big

입력이 10,-1,200,42인 경우, 출력은 다음과 같습니다:

ok: 10
negative
too big
ok: 42

치트 시트

오류를 던지는 함수(throwing function)try를 사용하여 다른 오류를 던지는 함수를 호출할 수 있습니다. 오류는 가장 가까운 do/catch 문으로 자동으로 전파됩니다:

enum AuthError: Error { case badUser, badPass }

func loadUser(_ name: String) throws -> String {
    if name.isEmpty { throw AuthError.badUser }
    return name
}

func login(_ name: String, _ pass: String) throws -> String {
    let u = try loadUser(name)   // error propagates up if thrown
    if pass.count < 4 { throw AuthError.badPass }
    return "hello \(u)"
}

do {
    print(try login("", "abcd"))
} catch AuthError.badUser {
    print("missing user")
} catch AuthError.badPass {
    print("weak password")
}

만약 loadUser에서 오류가 발생하면, login 함수의 나머지 실행은 건너뛰고 외부의 catch 문으로 직접 이동합니다. 수동으로 다시 던질(rethrowing) 필요가 없습니다.

직접 해보기

let parts = readLine()!.components(separatedBy: ",")

// TODO: enum StepError; parseSafe; capStrict; processStep;
// 각 파트에 대해 `processStep`을 `do/try`하고, 각 분기를 `catch`하여 출력하세요
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

로직 및 흐름의 모든 레슨