URLsession .failure 使应用程序崩溃,因为错误为零

URLsession .failure crash the app because error is nil

当我的状态代码为 500 时,我试图抛出错误。当我点击此行完成(.failure(error!))时,我遇到“致命错误:在展开可选值时意外发现 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

则响应和return消息
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))
    // }
    ...