¿Cuáles son las diferencias entre lanzamientos y repeticiones en Swift?

Después de buscar algunas referencias para resolverlo, desafortunadamente, no pude encontrar una descripción útil y simple sobre la comprensión de las diferencias entrethrows yrethrows. Es un poco confuso cuando tratamos de entender cómo debemos usarlos.

Mencionaría que estoy familiarizado con el -default-throws con su forma más simple para propagar un error, de la siguiente manera:

enum CustomError: Error {
    case potato
    case tomato
}

func throwCustomError(_ string: String) throws {
    if string.lowercased().trimmingCharacters(in: .whitespaces) == "potato" {
        throw CustomError.potato
    }

    if string.lowercased().trimmingCharacters(in: .whitespaces) == "tomato" {
        throw CustomError.tomato
    }
}

do {
    try throwCustomError("potato")
} catch let error as CustomError {
    switch error {
    case .potato:
        print("potatos catched") // potatos catched
    case .tomato:
        print("tomato catched")
    }
}

Hasta ahora todo bien, pero el problema surge cuando:

func throwCustomError(function:(String) throws -> ()) throws {
    try function("throws string")
}

func rethrowCustomError(function:(String) throws -> ()) rethrows {
    try function("rethrows string")
}

rethrowCustomError { string in
    print(string) // rethrows string
}

try throwCustomError { string in
    print(string) // throws string
}

lo que sé hasta ahora es cuando llamo a una función quethrows tiene que ser manejado por untrya diferencia derethrows. ¡¿Y qué?! ¿Cuál es la lógica que debemos seguir al decidir usarthrows orethrows?

Respuestas a la pregunta(2)

Su respuesta a la pregunta