I would like to throw error from within do block, if that is possible
I have a function getWeatherBy, it is signed as a throwing function. My code elsewhere in the app is depending on this throwing. I have inside of this function a JSONDecoder.decode that is throwing function itself, I have that inside of a do block. However, if there is an error with JSONDecoder, I would like to throw error from getWeatherBy, but since that throwing is happening inside of a JSONDecoder, it is being catched there.
Sorry for the messy code. I am still a newbie, any ideas how to make this code better is more than welcomed!
func getWeatherBy(city: String, completion: ((WeatherRecord) -> ())?) throws {
let trimmedCityName = (city as NSString).replacingOccurrences(of: " ", with: "+")
let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(trimmedCityName.lowercased())&appid=\(self.OpenWeatherAPIkey)&units=metric")
guard url != nil else { return }
print(url!)
let networkTask: URLSessionDataTask = URLSession.shared.dataTask(with: url!) {
(data, response, error) in
guard let data = data else { return }
do {
let decoded = try JSONDecoder().decode(WeatherData.self, from: data)
if (decoded.main != nil) {
if (decoded.coord?.lat != nil) {
DispatchQueue.main.async {
let record = WeatherRecord(temperature: Float(decoded.main!.temp), date: Date(), coordinates: CLLocationCoordinate2D(latitude: decoded.coord!.lat, longitude: decoded.coord!.lon), distance: 0.0)
if completion != nil {
completion!(record)
}
}
}
} else {
throw serviceError.cityNotFound
}
if (decoded.message != nil) {
print("Message: \(decoded.message!)")
DispatchQueue.main.async {
if (String(describing: decoded.message!).contains("Your account is temporary blocked") == true) {
}
if (decoded.message! != "Nothing to geocode") || String(describing: decoded.message!).contains("Your account is temporary blocked") != false {
}
}
}
} catch DecodingError.keyNotFound(let key, let context) {
Swift.print("Could not find key \(key) in JSON: \(context.debugDescription)")
} catch DecodingError.valueNotFound(let type, let context) {
Swift.print("Could not find type \(type) in JSON: \(context.debugDescription)")
} catch DecodingError.typeMismatch(let type, let context) {
Swift.print("Type mismatch for type \(type) in JSON: \(context.debugDescription) \(context)")
} catch DecodingError.dataCorrupted(let context) {
Swift.print("Data found to be corrupted in JSON: \(context.debugDescription)")
} catch let error as NSError {
NSLog("Error in read(from:ofType:) domain= \(error.domain), description= \(error.localizedDescription)")
}
}
The most common way is to add an error with / without new Result
func getWeatherBy(city: String, completion: ((WeatherRecord? , Error?) -> ()))
you can't throw from an asynchronous method immediately