apple/iOS, UIKit, Documentation

swift rethrows

lgvv 2025. 12. 3. 21:16

swift rethrows

 
 
함수나 메서드는 rethrows 키워드를 사용하여 선언할 수 있음.
이는 함수 매개변수 중 하나가 에러를 던질 경우에만 에러를 던진다는 것을 의미.
이러한 함수와 메서드를 rethrowing 함수(rethrowing functions) 또는 rethrowing 메서드(rethrowing methods)라고 부름.
 

func someFunction(callback: () throws -> Void) throws {
    try callback()
}


 

rethrowing 함수와 메서드는 적어도 하나의 throwing 함수 매개변수를 가져야 함.
rethrowing 함수나 메서드는 오직 catch 블록 안에서만 throw 문을 포함할 수 있음.
 
이 규칙을 통해 do-catch 구문 안에서 throwing 함수를 호출하고, catch 블록에서 다른 에러를 던지며 에러를 처리할 수 있음.
또한 catch 블록은 반드시 rethrowing 함수의 throwing 매개변수 중 하나가 던진 에러만 처리해야 함.
 
 
예를 들어, 다음 코드는 잘못된 코드입
왜냐하면 catch 블록에서 alwaysThrows()가 던진 에러를 처리하려고 하기 때문 

func alwaysThrows() throws {
    throw SomeError.error
}

func someFunction(callback: () throws -> Void) rethrows {
    do {
        try callback()
        try alwaysThrows()  // Invalid, alwaysThrows() isn't a throwing parameter
    } catch {
        throw AnotherError.error
    }
}


 
throwing 메서드는 rethrowing 메서드를 오버라이드할 수 없음.
throwing 메서드는 rethrowing 메서드에 대한 프로토콜 요구사항을 충족할 수 없음.
 
반대로, rethrowing 메서드는 throwing 메서드를 오버라이드할 수 있음.
rethrowing 메서드는 throwing 메서드에 대한 프로토콜 요구사항을 충족할 수 있음.

또한, rethrowing 대신 제네릭 코드에서 특정 에러 타입을 throw하는 방법을 사용할 수도 있음.
 

func someFunction<E: Error>(callback: () throws(E) -> Void) throws(E) {
    try callback()
}


 
이러한 방식으로 에러를 전달하면 에러 타입에 대한 정보를 그대로 보존할 수 있음.
하지만, rethrows로 함수를 표시하는 것과 달리, 이 방식은 동일한 타입의 에러를 함수가 직접 던지는 것을 막아주지는 않음.
 
 
 

코드 샘플

 

//
//  RethrowsExample.swift
//  ArchitetureExample
//
//  Created by Geon Woo lee on 12/2/25.
//

import Foundation

fileprivate enum SomeError: Error {
    case error
}

fileprivate enum AnotherError: Error {
    case error
}

fileprivate final class SomeClass {
    func alwaysThrows() throws {
        throw SomeError.error
    }
    
    func someFunction(callback: () throws -> Void) throws {
        try callback()
    }
    
//    func someFunction(callback: () throws -> Void) rethrows {
//        do {
//            try callback()
//            try alwaysThrows()  // Invalid, alwaysThrows() isn't a throwing parameter
//        } catch {
//            throw AnotherError.error
//        }
//    }
    
    func someFunction2(callback: () throws -> Void) rethrows {
        try callback()
    }
    
    func someFunction3(callback: () throws -> Void) throws {
        do {
            try callback()
            try alwaysThrows()
        } catch {
            throw AnotherError.error
        }
    }
    
    func someFunction4(callback: () throws -> Void) throws {
        do {
            try callback()
            try alwaysThrows()
        } catch {
            throw AnotherError.error
        }
    }
    
    func someFunction5<E: Error>(callback: () throws(E) -> Void) throws(E) {
        try callback()
    }
}

import SwiftUI

fileprivate struct PreviewView: View {
    var body: some View {
        Button {
            buttonTapped4()
        } label: {
            Text("Button")
        }
    }
    
    private func buttonTapped() {
        do {
            let someClass = SomeClass()
            try someClass.someFunction(callback: someClass.alwaysThrows)
        } catch {
            print(type(of: error)) // SomeError
        }
    }
    
    private func buttonTapped2() {
        do {
            let someClass = SomeClass()
            try someClass.someFunction2(callback: someClass.alwaysThrows)
        } catch {
            print(type(of: error))
        }
    }
    
    private func buttonTapped3() {
        do {
            let someClass = SomeClass()
            try someClass.someFunction3 { }
        } catch {
            print(type(of: error)) // AnotherError
        }
    }
    
    private func buttonTapped4() {
        do {
            let someClass = SomeClass()
            try someClass.someFunction4 { }
        } catch {
            print(type(of: error)) // AnotherError
        }
    }
    
    private func buttonTapped5() {
        let someClass = SomeClass()
        someClass.someFunction5 { }
    }
}

#Preview {
    PreviewView()
}

 
 
 
(참고)
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/declarations