Browse Source

ParameterEncoding encode API now throws instead of returning tuple.

Christian Noon 9 years ago
parent
commit
25b8cf0fca

+ 20 - 0
Source/AFError.swift

@@ -31,6 +31,12 @@ import Foundation
 /// - responseValidationFailed:    Returned when a `validate()` call fails.
 /// - responseSerializationFailed: Returned when a response serializer encounters an error in the serialization process.
 public enum AFError: Error {
+    // TODO: Need docstring...also need above!
+    public enum ParameterEncodingFailureReason {
+        case jsonSerializationFailed(error: Error)
+        case propertyListSerializationFailed(error: Error)
+    }
+
     /// The underlying reason the multipart encoding error occurred.
     ///
     /// - bodyPartURLInvalid:                   The `fileURL` provided for reading an encodable body part isn't a
@@ -110,6 +116,7 @@ public enum AFError: Error {
         case propertyListSerializationFailed(error: Error)
     }
 
+    case parameterEncodingFailed(reason: ParameterEncodingFailureReason)
     case multipartEncodingFailed(reason: MultipartEncodingFailureReason)
     case responseValidationFailed(reason: ValidationFailureReason)
     case responseSerializationFailed(reason: SerializationFailureReason)
@@ -286,6 +293,8 @@ extension AFError.SerializationFailureReason {
 extension AFError: LocalizedError {
     public var errorDescription: String? {
         switch self {
+        case .parameterEncodingFailed(let reason):
+            return reason.localizedDescription
         case .multipartEncodingFailed(let reason):
             return reason.localizedDescription
         case .responseValidationFailed(let reason):
@@ -296,6 +305,17 @@ extension AFError: LocalizedError {
     }
 }
 
+extension AFError.ParameterEncodingFailureReason {
+    var localizedDescription: String {
+        switch self {
+        case .jsonSerializationFailed(let error):
+            return "JSON could not be serialized because of error:\n\(error.localizedDescription)"
+        case .propertyListSerializationFailed(let error):
+            return "PropertyList could not be serialized because of error:\n\(error.localizedDescription)"
+        }
+    }
+}
+
 extension AFError.MultipartEncodingFailureReason {
     var localizedDescription: String {
         switch self {

+ 9 - 13
Source/ParameterEncoding.swift

@@ -70,25 +70,21 @@ public enum ParameterEncoding {
     case urlEncodedInURL
     case json
     case propertyList(PropertyListSerialization.PropertyListFormat, PropertyListSerialization.WriteOptions)
-    case custom((URLRequestConvertible, [String: Any]?) -> (URLRequest, Error?))
+    case custom((URLRequestConvertible, [String: Any]?) throws -> URLRequest)
 
     /// Creates a URL request by encoding parameters and applying them onto an existing request.
     ///
     /// - parameter urlRequest: The request to have parameters applied.
     /// - parameter parameters: The parameters to apply.
     ///
+    /// - throws: An `AFError.parameterEncodingFailed` error if json or property list serialization fails.
+    ///
     /// - returns: A tuple containing the constructed request and the error that occurred during parameter encoding,
     ///            if any.
-    public func encode(
-        _ urlRequest: URLRequestConvertible,
-        parameters: [String: Any]?)
-        -> (URLRequest, Error?)
-    {
+    public func encode(_ urlRequest: URLRequestConvertible, with parameters: [String: Any]?) throws -> URLRequest {
         var urlRequest = urlRequest.urlRequest
 
-        guard let parameters = parameters else { return (urlRequest, nil) }
-
-        var encodingError: Error? = nil
+        guard let parameters = parameters else { return urlRequest }
 
         switch self {
         case .url, .urlEncodedInURL:
@@ -151,7 +147,7 @@ public enum ParameterEncoding {
 
                 urlRequest.httpBody = data
             } catch {
-                encodingError = error
+                throw AFError.parameterEncodingFailed(reason: .jsonSerializationFailed(error: error))
             }
         case .propertyList(let format, let options):
             do {
@@ -167,13 +163,13 @@ public enum ParameterEncoding {
 
                 urlRequest.httpBody = data
             } catch {
-                encodingError = error
+                throw AFError.parameterEncodingFailed(reason: .propertyListSerializationFailed(error: error))
             }
         case .custom(let closure):
-            (urlRequest, encodingError) = closure(urlRequest, parameters)
+            urlRequest = try closure(urlRequest, parameters)
         }
 
-        return (urlRequest, encodingError)
+        return urlRequest
     }
 
     /// Creates percent-escaped, URL encoded query string components from the given key-value pair using recursion.

+ 16 - 4
Source/SessionManager.swift

@@ -232,9 +232,15 @@ open class SessionManager {
         -> DataRequest
     {
         let urlRequest = URLRequest(urlString: urlString, method: method, headers: headers)
-        let encodedURLRequest = encoding.encode(urlRequest, parameters: parameters).0
 
-        return request(resource: encodedURLRequest)
+        do {
+            let encodedURLRequest = try encoding.encode(urlRequest, with: parameters)
+            return request(resource: encodedURLRequest)
+        } catch {
+            let request = self.request(resource: urlRequest)
+            request.delegate.error = error
+            return request
+        }
     }
 
     /// Creates a `DataRequest` to retrieve the contents of a URL based on the specified `urlRequest`.
@@ -289,9 +295,15 @@ open class SessionManager {
         -> DownloadRequest
     {
         let urlRequest = URLRequest(urlString: urlString, method: method, headers: headers)
-        let encodedURLRequest = encoding.encode(urlRequest, parameters: parameters).0
 
-        return download(resource: encodedURLRequest, to: destination)
+        do {
+            let encodedURLRequest = try encoding.encode(urlRequest, with: parameters)
+            return download(resource: encodedURLRequest, to: destination)
+        } catch {
+            let request = download(resource: urlRequest, to: destination)
+            request.delegate.error = error
+            return request
+        }
     }
 
     /// Creates a `DownloadRequest` to retrieve the contents of a URL based on the specified `urlRequest` and save

+ 5 - 1
Tests/CacheTests.swift

@@ -171,7 +171,11 @@ class CacheTestCase: BaseTestCase {
         var urlRequest = URLRequest(url: url, cachePolicy: cachePolicy, timeoutInterval: requestTimeout)
         urlRequest.httpMethod = HTTPMethod.get.rawValue
 
-        return ParameterEncoding.url.encode(urlRequest, parameters: parameters).0
+        do {
+            return try ParameterEncoding.url.encode(urlRequest, with: parameters)
+        } catch {
+            return urlRequest
+        }
     }
 
     @discardableResult

File diff suppressed because it is too large
+ 544 - 401
Tests/ParameterEncodingTests.swift


+ 5 - 1
Tests/URLProtocolTests.swift

@@ -61,7 +61,11 @@ class ProxyURLProtocol: URLProtocol {
 
     override class func canonicalRequest(for request: URLRequest) -> URLRequest {
         if let headers = request.allHTTPHeaderFields {
-            return ParameterEncoding.url.encode(request, parameters: headers).0
+            do {
+                return try ParameterEncoding.url.encode(request, with: headers)
+            } catch {
+                return request
+            }
         }
 
         return request

Some files were not shown because too many files changed in this diff