`whenComplete` does not work without wait()
Closed this issue · 2 comments
Hi, I'm new with swift-nio and want to make a simple swift cli tool that sends an API request. I tried following the readme to do something like this in my swift code
httpClient.execute(request: request).whenComplete { result in
dump(result)
switch result {
case .failure(let error):
print("Error \(error)")
case .success(let response):
print("Response: \(response)")
if response.status == .ok {
print("Response: \(response)")
} else {
print("Response is not ok")
}
}
}
the output error is
▿ Swift.Result<AsyncHTTPClient.HTTPClient.Response, Swift.Error>.failure
▿ failure: HTTPClientError.cancelled
- code: AsyncHTTPClient.HTTPClientError.(unknown context at $10587c078).Code.cancelled
One google result leads me to this same problem https://stackoverflow.com/questions/59434813/how-to-use-async-http-client
and the answer is, rather than using whenComplete , i should do it like this
let future = httpClient.execute(request: request)
let response = try future.wait()
print(response)
How can I make the whenComplete
works?
When I just add a line try future.wait()
... it works but i need to discard its response too?
Thanks for your help!
The problem is probably that httpClient
is shutdown before the request is finished and therefore canceled.
Maybe you have a defer { httpClient.shutdonw() }
or similar in your code which is executed immediately after you started your request because whenComplete
returns immediately. On the other hand, .wait()
waits until the request is finished and the httpClient is only shutdown afterwards. Can you show as the code which creates and also eventually shutdowns the HTTPClient
?
Similar issue: #477
BTW: If you can use Swift 5.5.2
or higher, I would suggest you to use the new async/await API. Here is an example how to use it:
async-http-client/Examples/GetJSON/GetJSON.swift
Lines 36 to 50 in 71af9c7
Hi, ah okay thanks I guess this code works for now.. yeah for some reasons, i'm not able to use async/await for now
Thanks for the help @dnadoba
let future = httpClient.execute(request: request)
defer {
_ = try? future.wait() // --> gotta discard the result here
try? httpClient.syncShutdown()
}
httpClient.execute(request: request).whenComplete { result in
dump(result)
switch result {
case .failure(let error):
print("Error \(error)")
case .success(let response):
print("Response: \(response)")
if response.status == .ok {
print("Response: \(response)")
} else {
print("Response is not ok")
}
}
}