问题描述
当我有状态代码 500 时,我试图抛出一个错误。当我点击此行完成时(.failure(错误!))我有“致命错误:在解开可选值时意外发现 nil”是它们是我的 URL 会话功能有问题吗?
func PutRoleLedgerTransaction_DebitdistributorBalance(...,completion: @escaping (Result<Data,Error>) -> Void){
let jsonData = role_ledger_object.data(using: .utf8)
let componentURL = createURLComponents(path: "")
print(componentURL.url!)
guard let validURL = componentURL.url else {
print("URL creation Failed...")
return
}
var request = URLRequest(url:validURL)
request.setValue("application/json",forHTTPHeaderField: "Content-Type" )
request.setValue("application/json",forHTTPHeaderField: "Accept" )
request.httpMethod = "PUT"
request.httpBody = jsonData
URLSession.shared.dataTask(with: request) { (data,response,error) in
if let httpResponse = response as? HTTPURLResponse {
print("PutRoleLedgerTransaction API status: \(httpResponse.statusCode)")
let message: String = HTTPURLResponse.localizedString(forStatusCode: httpResponse.statusCode)
print("httpResponse.allHeaderFields \(message)")
if httpResponse.statusCode > 300{
completion(.failure(error!))
return
}
}
guard let validData = data,error == nil else {
completion(.failure(error!))
return
}
do {
completion(.success(validData))
} catch let serializationError {
completion(.failure(serializationError))
}
}.resume()
}
解决方法
服务器 500 响应不一定等于 URLSession
错误,您不能粗心地打开可选项。
创建自定义错误
enum HTTPResponseError : Error {
case serverFailed(String)
}
在闭包中先处理URLSession
错误,然后响应,如果状态码不是200则返回消息
URLSession.shared.dataTask(with: request) { (data,response,error) in
if let error = error { completion(.failure(error)); return }
if let httpResponse = response as? HTTPURLResponse {
print("PutRoleLedgerTransaction API status: \(httpResponse.statusCode)")
let message: String = HTTPURLResponse.localizedString(forStatusCode: httpResponse.statusCode)
print("httpResponse.allHeaderFields \(message)")
if httpResponse.statusCode != 200 {
completion(.failure(HTTPResponseError.serverFailed(message)))
return
}
}
// The do block makes no sense if no error is being thrown
// do {
// force unwrapping data is safe if error is nil.
completion(.success(data!))
// } catch {
// completion(.failure(error))
// }
...