First of all I have a function for get version from API.
func getVersionAsync() async throws -> VersionEntity {
return try await withCheckedThrowingContinuation { continuation in
versionTask.getVersion { result in
switch result {
case .success(let response):
continuation.resume(returning: response.item)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
Then I need to handle it or repeat request after 5 seconds:
func checkVersion() async {
do {
let versionEntity = try await getVersionAsync()
// handle versionEntity
} catch {
try await Task.sleep(nanoseconds: 5) <- Errors thrown from here are not handled
await checkVersion()
}
}
There is an error Errors thrown from here are not handled
. What is the correct way to do this in swift concurrency?
I would add throws
to the function signature so that the function exits if the sleep
call throws an error. This for instance means that the functions exits if the surrounding Task
is cancelled.
func checkVersion() async throws {
do {
let versionEntity = try await getVersionAsync()
// handle versionEntity
} catch {
try await Task.sleep(for: .seconds(5))
try await checkVersion()
}
}
Note that I changed the sleep to 5 seconds as that was the time given in the text.
If you don't want to use recursion then you could wrap the do/catch
in a while loop. Here I also added a max tries parameter
func checkVersion(maxRetries: Int) async throws {
var allDone = false
var counter = 0
while allDone == false {
do {
counter += 1
let versionEntity = try await getVersionAsync()
// handle versionEntity
allDone = true
} catch {
if counter > maxRetries { return } // or maybe throw an error
try await Task.sleep(for: .seconds(5))
}
}
}