| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840 | ////  AFError.swift////  Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)////  Permission is hereby granted, free of charge, to any person obtaining a copy//  of this software and associated documentation files (the "Software"), to deal//  in the Software without restriction, including without limitation the rights//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell//  copies of the Software, and to permit persons to whom the Software is//  furnished to do so, subject to the following conditions:////  The above copyright notice and this permission notice shall be included in//  all copies or substantial portions of the Software.////  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN//  THE SOFTWARE.//import Foundation/// `AFError` is the error type returned by Alamofire. It encompasses a few different types of errors, each with/// their own associated reasons.public enum AFError: Error {    /// The underlying reason the `.multipartEncodingFailed` error occurred.    public enum MultipartEncodingFailureReason {        /// The `fileURL` provided for reading an encodable body part isn't a file `URL`.        case bodyPartURLInvalid(url: URL)        /// The filename of the `fileURL` provided has either an empty `lastPathComponent` or `pathExtension.        case bodyPartFilenameInvalid(in: URL)        /// The file at the `fileURL` provided was not reachable.        case bodyPartFileNotReachable(at: URL)        /// Attempting to check the reachability of the `fileURL` provided threw an error.        case bodyPartFileNotReachableWithError(atURL: URL, error: Error)        /// The file at the `fileURL` provided is actually a directory.        case bodyPartFileIsDirectory(at: URL)        /// The size of the file at the `fileURL` provided was not returned by the system.        case bodyPartFileSizeNotAvailable(at: URL)        /// The attempt to find the size of the file at the `fileURL` provided threw an error.        case bodyPartFileSizeQueryFailedWithError(forURL: URL, error: Error)        /// An `InputStream` could not be created for the provided `fileURL`.        case bodyPartInputStreamCreationFailed(for: URL)        /// An `OutputStream` could not be created when attempting to write the encoded data to disk.        case outputStreamCreationFailed(for: URL)        /// The encoded body data could not be written to disk because a file already exists at the provided `fileURL`.        case outputStreamFileAlreadyExists(at: URL)        /// The `fileURL` provided for writing the encoded body data to disk is not a file `URL`.        case outputStreamURLInvalid(url: URL)        /// The attempt to write the encoded body data to disk failed with an underlying error.        case outputStreamWriteFailed(error: Error)        /// The attempt to read an encoded body part `InputStream` failed with underlying system error.        case inputStreamReadFailed(error: Error)    }    /// The underlying reason the `.parameterEncodingFailed` error occurred.    public enum ParameterEncodingFailureReason {        /// The `URLRequest` did not have a `URL` to encode.        case missingURL        /// JSON serialization failed with an underlying system error during the encoding process.        case jsonEncodingFailed(error: Error)        /// Custom parameter encoding failed due to the associated `Error`.        case customEncodingFailed(error: Error)    }    /// The underlying reason the `.parameterEncoderFailed` error occurred.    public enum ParameterEncoderFailureReason {        /// Possible missing components.        public enum RequiredComponent {            /// The `URL` was missing or unable to be extracted from the passed `URLRequest` or during encoding.            case url            /// The `HTTPMethod` could not be extracted from the passed `URLRequest`.            case httpMethod(rawValue: String)        }        /// A `RequiredComponent` was missing during encoding.        case missingRequiredComponent(RequiredComponent)        /// The underlying encoder failed with the associated error.        case encoderFailed(error: Error)    }    /// The underlying reason the `.responseValidationFailed` error occurred.    public enum ResponseValidationFailureReason {        /// The data file containing the server response did not exist.        case dataFileNil        /// The data file containing the server response at the associated `URL` could not be read.        case dataFileReadFailed(at: URL)        /// The response did not contain a `Content-Type` and the `acceptableContentTypes` provided did not contain a        /// wildcard type.        case missingContentType(acceptableContentTypes: [String])        /// The response `Content-Type` did not match any type in the provided `acceptableContentTypes`.        case unacceptableContentType(acceptableContentTypes: [String], responseContentType: String)        /// The response status code was not acceptable.        case unacceptableStatusCode(code: Int)        /// Custom response validation failed due to the associated `Error`.        case customValidationFailed(error: Error)    }    /// The underlying reason the response serialization error occurred.    public enum ResponseSerializationFailureReason {        /// The server response contained no data or the data was zero length.        case inputDataNilOrZeroLength        /// The file containing the server response did not exist.        case inputFileNil        /// The file containing the server response could not be read from the associated `URL`.        case inputFileReadFailed(at: URL)        /// String serialization failed using the provided `String.Encoding`.        case stringSerializationFailed(encoding: String.Encoding)        /// JSON serialization failed with an underlying system error.        case jsonSerializationFailed(error: Error)        /// A `DataDecoder` failed to decode the response due to the associated `Error`.        case decodingFailed(error: Error)        /// A custom response serializer failed due to the associated `Error`.        case customSerializationFailed(error: Error)        /// Generic serialization failed for an empty response that wasn't type `Empty` but instead the associated type.        case invalidEmptyResponse(type: String)    }    /// Underlying reason a server trust evaluation error occurred.    public enum ServerTrustFailureReason {        /// The output of a server trust evaluation.        public struct Output {            /// The host for which the evaluation was performed.            public let host: String            /// The `SecTrust` value which was evaluated.            public let trust: SecTrust            /// The `OSStatus` of evaluation operation.            public let status: OSStatus            /// The result of the evaluation operation.            public let result: SecTrustResultType            /// Creates an `Output` value from the provided values.            init(_ host: String, _ trust: SecTrust, _ status: OSStatus, _ result: SecTrustResultType) {                self.host = host                self.trust = trust                self.status = status                self.result = result            }        }        /// No `ServerTrustEvaluator` was found for the associated host.        case noRequiredEvaluator(host: String)        /// No certificates were found with which to perform the trust evaluation.        case noCertificatesFound        /// No public keys were found with which to perform the trust evaluation.        case noPublicKeysFound        /// During evaluation, application of the associated `SecPolicy` failed.        case policyApplicationFailed(trust: SecTrust, policy: SecPolicy, status: OSStatus)        /// During evaluation, setting the associated anchor certificates failed.        case settingAnchorCertificatesFailed(status: OSStatus, certificates: [SecCertificate])        /// During evaluation, creation of the revocation policy failed.        case revocationPolicyCreationFailed        /// `SecTrust` evaluation failed with the associated `Error`, if one was produced.        case trustEvaluationFailed(error: Error?)        /// Default evaluation failed with the associated `Output`.        case defaultEvaluationFailed(output: Output)        /// Host validation failed with the associated `Output`.        case hostValidationFailed(output: Output)        /// Revocation check failed with the associated `Output` and options.        case revocationCheckFailed(output: Output, options: RevocationTrustEvaluator.Options)        /// Certificate pinning failed.        case certificatePinningFailed(host: String, trust: SecTrust, pinnedCertificates: [SecCertificate], serverCertificates: [SecCertificate])        /// Public key pinning failed.        case publicKeyPinningFailed(host: String, trust: SecTrust, pinnedKeys: [SecKey], serverKeys: [SecKey])        /// Custom server trust evaluation failed due to the associated `Error`.        case customEvaluationFailed(error: Error)    }    /// The underlying reason the `.urlRequestValidationFailed`    public enum URLRequestValidationFailureReason {        /// URLRequest with GET method had body data.        case bodyDataInGETRequest(Data)    }    ///  `UploadableConvertible` threw an error in `createUploadable()`.    case createUploadableFailed(error: Error)    ///  `URLRequestConvertible` threw an error in `asURLRequest()`.    case createURLRequestFailed(error: Error)    /// `SessionDelegate` threw an error while attempting to move downloaded file to destination URL.    case downloadedFileMoveFailed(error: Error, source: URL, destination: URL)    /// `Request` was explicitly cancelled.    case explicitlyCancelled    /// `URLConvertible` type failed to create a valid `URL`.    case invalidURL(url: URLConvertible)    /// Multipart form encoding failed.    case multipartEncodingFailed(reason: MultipartEncodingFailureReason)    /// `ParameterEncoding` threw an error during the encoding process.    case parameterEncodingFailed(reason: ParameterEncodingFailureReason)    /// `ParameterEncoder` threw an error while running the encoder.    case parameterEncoderFailed(reason: ParameterEncoderFailureReason)    /// `RequestAdapter` threw an error during adaptation.    case requestAdaptationFailed(error: Error)    /// `RequestRetrier` threw an error during the request retry process.    case requestRetryFailed(retryError: Error, originalError: Error)    /// Response validation failed.    case responseValidationFailed(reason: ResponseValidationFailureReason)    /// Response serialization failed.    case responseSerializationFailed(reason: ResponseSerializationFailureReason)    /// `ServerTrustEvaluating` instance threw an error during trust evaluation.    case serverTrustEvaluationFailed(reason: ServerTrustFailureReason)    /// `Session` which issued the `Request` was deinitialized, most likely because its reference went out of scope.    case sessionDeinitialized    /// `Session` was explicitly invalidated, possibly with the `Error` produced by the underlying `URLSession`.    case sessionInvalidated(error: Error?)    /// `URLSessionTask` completed with error.    case sessionTaskFailed(error: Error)    /// `URLRequest` failed validation.    case urlRequestValidationFailed(reason: URLRequestValidationFailureReason)}extension Error {    /// Returns the instance cast as an `AFError`.    public var asAFError: AFError? {        self as? AFError    }    /// Returns the instance cast as an `AFError`. If casting fails, a `fatalError` with the specified `message` is thrown.    public func asAFError(orFailWith message: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) -> AFError {        guard let afError = self as? AFError else {            fatalError(message(), file: file, line: line)        }        return afError    }    /// Casts the instance as `AFError` or returns `defaultAFError`    func asAFError(or defaultAFError: @autoclosure () -> AFError) -> AFError {        self as? AFError ?? defaultAFError()    }}// MARK: - Error Booleansextension AFError {    /// Returns whether the instance is `.sessionDeinitialized`.    public var isSessionDeinitializedError: Bool {        if case .sessionDeinitialized = self { return true }        return false    }    /// Returns whether the instance is `.sessionInvalidated`.    public var isSessionInvalidatedError: Bool {        if case .sessionInvalidated = self { return true }        return false    }    /// Returns whether the instance is `.explicitlyCancelled`.    public var isExplicitlyCancelledError: Bool {        if case .explicitlyCancelled = self { return true }        return false    }    /// Returns whether the instance is `.invalidURL`.    public var isInvalidURLError: Bool {        if case .invalidURL = self { return true }        return false    }    /// Returns whether the instance is `.parameterEncodingFailed`. When `true`, the `underlyingError` property will    /// contain the associated value.    public var isParameterEncodingError: Bool {        if case .parameterEncodingFailed = self { return true }        return false    }    /// Returns whether the instance is `.parameterEncoderFailed`. When `true`, the `underlyingError` property will    /// contain the associated value.    public var isParameterEncoderError: Bool {        if case .parameterEncoderFailed = self { return true }        return false    }    /// Returns whether the instance is `.multipartEncodingFailed`. When `true`, the `url` and `underlyingError`    /// properties will contain the associated values.    public var isMultipartEncodingError: Bool {        if case .multipartEncodingFailed = self { return true }        return false    }    /// Returns whether the instance is `.requestAdaptationFailed`. When `true`, the `underlyingError` property will    /// contain the associated value.    public var isRequestAdaptationError: Bool {        if case .requestAdaptationFailed = self { return true }        return false    }    /// Returns whether the instance is `.responseValidationFailed`. When `true`, the `acceptableContentTypes`,    /// `responseContentType`,  `responseCode`, and `underlyingError` properties will contain the associated values.    public var isResponseValidationError: Bool {        if case .responseValidationFailed = self { return true }        return false    }    /// Returns whether the instance is `.responseSerializationFailed`. When `true`, the `failedStringEncoding` and    /// `underlyingError` properties will contain the associated values.    public var isResponseSerializationError: Bool {        if case .responseSerializationFailed = self { return true }        return false    }    /// Returns whether the instance is `.serverTrustEvaluationFailed`. When `true`, the `underlyingError` property will    /// contain the associated value.    public var isServerTrustEvaluationError: Bool {        if case .serverTrustEvaluationFailed = self { return true }        return false    }    /// Returns whether the instance is `requestRetryFailed`. When `true`, the `underlyingError` property will    /// contain the associated value.    public var isRequestRetryError: Bool {        if case .requestRetryFailed = self { return true }        return false    }    /// Returns whether the instance is `createUploadableFailed`. When `true`, the `underlyingError` property will    /// contain the associated value.    public var isCreateUploadableError: Bool {        if case .createUploadableFailed = self { return true }        return false    }    /// Returns whether the instance is `createURLRequestFailed`. When `true`, the `underlyingError` property will    /// contain the associated value.    public var isCreateURLRequestError: Bool {        if case .createURLRequestFailed = self { return true }        return false    }    /// Returns whether the instance is `downloadedFileMoveFailed`. When `true`, the `destination` and `underlyingError` properties will    /// contain the associated values.    public var isDownloadedFileMoveError: Bool {        if case .downloadedFileMoveFailed = self { return true }        return false    }    /// Returns whether the instance is `createURLRequestFailed`. When `true`, the `underlyingError` property will    /// contain the associated value.    public var isSessionTaskError: Bool {        if case .sessionTaskFailed = self { return true }        return false    }}// MARK: - Convenience Propertiesextension AFError {    /// The `URLConvertible` associated with the error.    public var urlConvertible: URLConvertible? {        guard case let .invalidURL(url) = self else { return nil }        return url    }    /// The `URL` associated with the error.    public var url: URL? {        guard case let .multipartEncodingFailed(reason) = self else { return nil }        return reason.url    }    /// The underlying `Error` responsible for generating the failure associated with `.sessionInvalidated`,    /// `.parameterEncodingFailed`, `.parameterEncoderFailed`, `.multipartEncodingFailed`, `.requestAdaptationFailed`,    /// `.responseSerializationFailed`, `.requestRetryFailed` errors.    public var underlyingError: Error? {        switch self {        case let .multipartEncodingFailed(reason):            return reason.underlyingError        case let .parameterEncodingFailed(reason):            return reason.underlyingError        case let .parameterEncoderFailed(reason):            return reason.underlyingError        case let .requestAdaptationFailed(error):            return error        case let .requestRetryFailed(retryError, _):            return retryError        case let .responseValidationFailed(reason):            return reason.underlyingError        case let .responseSerializationFailed(reason):            return reason.underlyingError        case let .serverTrustEvaluationFailed(reason):            return reason.underlyingError        case let .sessionInvalidated(error):            return error        case let .createUploadableFailed(error):            return error        case let .createURLRequestFailed(error):            return error        case let .downloadedFileMoveFailed(error, _, _):            return error        case let .sessionTaskFailed(error):            return error        case .explicitlyCancelled,             .invalidURL,             .sessionDeinitialized,             .urlRequestValidationFailed:            return nil        }    }    /// The acceptable `Content-Type`s of a `.responseValidationFailed` error.    public var acceptableContentTypes: [String]? {        guard case let .responseValidationFailed(reason) = self else { return nil }        return reason.acceptableContentTypes    }    /// The response `Content-Type` of a `.responseValidationFailed` error.    public var responseContentType: String? {        guard case let .responseValidationFailed(reason) = self else { return nil }        return reason.responseContentType    }    /// The response code of a `.responseValidationFailed` error.    public var responseCode: Int? {        guard case let .responseValidationFailed(reason) = self else { return nil }        return reason.responseCode    }    /// The `String.Encoding` associated with a failed `.stringResponse()` call.    public var failedStringEncoding: String.Encoding? {        guard case let .responseSerializationFailed(reason) = self else { return nil }        return reason.failedStringEncoding    }    /// The `source` URL of a `.downloadedFileMoveFailed` error.    public var sourceURL: URL? {        guard case let .downloadedFileMoveFailed(_, source, _) = self else { return nil }        return source    }    /// The `destination` URL of a `.downloadedFileMoveFailed` error.    public var destinationURL: URL? {        guard case let .downloadedFileMoveFailed(_, _, destination) = self else { return nil }        return destination    }}extension AFError.ParameterEncodingFailureReason {    var underlyingError: Error? {        switch self {        case let .jsonEncodingFailed(error),             let .customEncodingFailed(error):            return error        case .missingURL:            return nil        }    }}extension AFError.ParameterEncoderFailureReason {    var underlyingError: Error? {        switch self {        case let .encoderFailed(error):            return error        case .missingRequiredComponent:            return nil        }    }}extension AFError.MultipartEncodingFailureReason {    var url: URL? {        switch self {        case let .bodyPartURLInvalid(url),             let .bodyPartFilenameInvalid(url),             let .bodyPartFileNotReachable(url),             let .bodyPartFileIsDirectory(url),             let .bodyPartFileSizeNotAvailable(url),             let .bodyPartInputStreamCreationFailed(url),             let .outputStreamCreationFailed(url),             let .outputStreamFileAlreadyExists(url),             let .outputStreamURLInvalid(url),             let .bodyPartFileNotReachableWithError(url, _),             let .bodyPartFileSizeQueryFailedWithError(url, _):            return url        case .outputStreamWriteFailed,             .inputStreamReadFailed:            return nil        }    }    var underlyingError: Error? {        switch self {        case let .bodyPartFileNotReachableWithError(_, error),             let .bodyPartFileSizeQueryFailedWithError(_, error),             let .outputStreamWriteFailed(error),             let .inputStreamReadFailed(error):            return error        case .bodyPartURLInvalid,             .bodyPartFilenameInvalid,             .bodyPartFileNotReachable,             .bodyPartFileIsDirectory,             .bodyPartFileSizeNotAvailable,             .bodyPartInputStreamCreationFailed,             .outputStreamCreationFailed,             .outputStreamFileAlreadyExists,             .outputStreamURLInvalid:            return nil        }    }}extension AFError.ResponseValidationFailureReason {    var acceptableContentTypes: [String]? {        switch self {        case let .missingContentType(types),             let .unacceptableContentType(types, _):            return types        case .dataFileNil,             .dataFileReadFailed,             .unacceptableStatusCode,             .customValidationFailed:            return nil        }    }    var responseContentType: String? {        switch self {        case let .unacceptableContentType(_, responseType):            return responseType        case .dataFileNil,             .dataFileReadFailed,             .missingContentType,             .unacceptableStatusCode,             .customValidationFailed:            return nil        }    }    var responseCode: Int? {        switch self {        case let .unacceptableStatusCode(code):            return code        case .dataFileNil,             .dataFileReadFailed,             .missingContentType,             .unacceptableContentType,             .customValidationFailed:            return nil        }    }    var underlyingError: Error? {        switch self {        case let .customValidationFailed(error):            return error        case .dataFileNil,             .dataFileReadFailed,             .missingContentType,             .unacceptableContentType,             .unacceptableStatusCode:            return nil        }    }}extension AFError.ResponseSerializationFailureReason {    var failedStringEncoding: String.Encoding? {        switch self {        case let .stringSerializationFailed(encoding):            return encoding        case .inputDataNilOrZeroLength,             .inputFileNil,             .inputFileReadFailed(_),             .jsonSerializationFailed(_),             .decodingFailed(_),             .customSerializationFailed(_),             .invalidEmptyResponse:            return nil        }    }    var underlyingError: Error? {        switch self {        case let .jsonSerializationFailed(error),             let .decodingFailed(error),             let .customSerializationFailed(error):            return error        case .inputDataNilOrZeroLength,             .inputFileNil,             .inputFileReadFailed,             .stringSerializationFailed,             .invalidEmptyResponse:            return nil        }    }}extension AFError.ServerTrustFailureReason {    var output: AFError.ServerTrustFailureReason.Output? {        switch self {        case let .defaultEvaluationFailed(output),             let .hostValidationFailed(output),             let .revocationCheckFailed(output, _):            return output        case .noRequiredEvaluator,             .noCertificatesFound,             .noPublicKeysFound,             .policyApplicationFailed,             .settingAnchorCertificatesFailed,             .revocationPolicyCreationFailed,             .trustEvaluationFailed,             .certificatePinningFailed,             .publicKeyPinningFailed,             .customEvaluationFailed:            return nil        }    }    var underlyingError: Error? {        switch self {        case let .customEvaluationFailed(error):            return error        case let .trustEvaluationFailed(error):            return error        case .noRequiredEvaluator,             .noCertificatesFound,             .noPublicKeysFound,             .policyApplicationFailed,             .settingAnchorCertificatesFailed,             .revocationPolicyCreationFailed,             .defaultEvaluationFailed,             .hostValidationFailed,             .revocationCheckFailed,             .certificatePinningFailed,             .publicKeyPinningFailed:            return nil        }    }}// MARK: - Error Descriptionsextension AFError: LocalizedError {    public var errorDescription: String? {        switch self {        case .explicitlyCancelled:            return "Request explicitly cancelled."        case let .invalidURL(url):            return "URL is not valid: \(url)"        case let .parameterEncodingFailed(reason):            return reason.localizedDescription        case let .parameterEncoderFailed(reason):            return reason.localizedDescription        case let .multipartEncodingFailed(reason):            return reason.localizedDescription        case let .requestAdaptationFailed(error):            return "Request adaption failed with error: \(error.localizedDescription)"        case let .responseValidationFailed(reason):            return reason.localizedDescription        case let .responseSerializationFailed(reason):            return reason.localizedDescription        case let .requestRetryFailed(retryError, originalError):            return """            Request retry failed with retry error: \(retryError.localizedDescription), \            original error: \(originalError.localizedDescription)            """        case .sessionDeinitialized:            return """            Session was invalidated without error, so it was likely deinitialized unexpectedly. \            Be sure to retain a reference to your Session for the duration of your requests.            """        case let .sessionInvalidated(error):            return "Session was invalidated with error: \(error?.localizedDescription ?? "No description.")"        case let .serverTrustEvaluationFailed(reason):            return "Server trust evaluation failed due to reason: \(reason.localizedDescription)"        case let .urlRequestValidationFailed(reason):            return "URLRequest validation failed due to reason: \(reason.localizedDescription)"        case let .createUploadableFailed(error):            return "Uploadable creation failed with error: \(error.localizedDescription)"        case let .createURLRequestFailed(error):            return "URLRequest creation failed with error: \(error.localizedDescription)"        case let .downloadedFileMoveFailed(error, source, destination):            return "Moving downloaded file from: \(source) to: \(destination) failed with error: \(error.localizedDescription)"        case let .sessionTaskFailed(error):            return "URLSessionTask failed with error: \(error.localizedDescription)"        }    }}extension AFError.ParameterEncodingFailureReason {    var localizedDescription: String {        switch self {        case .missingURL:            return "URL request to encode was missing a URL"        case let .jsonEncodingFailed(error):            return "JSON could not be encoded because of error:\n\(error.localizedDescription)"        case let .customEncodingFailed(error):            return "Custom parameter encoder failed with error: \(error.localizedDescription)"        }    }}extension AFError.ParameterEncoderFailureReason {    var localizedDescription: String {        switch self {        case let .missingRequiredComponent(component):            return "Encoding failed due to a missing request component: \(component)"        case let .encoderFailed(error):            return "The underlying encoder failed with the error: \(error)"        }    }}extension AFError.MultipartEncodingFailureReason {    var localizedDescription: String {        switch self {        case let .bodyPartURLInvalid(url):            return "The URL provided is not a file URL: \(url)"        case let .bodyPartFilenameInvalid(url):            return "The URL provided does not have a valid filename: \(url)"        case let .bodyPartFileNotReachable(url):            return "The URL provided is not reachable: \(url)"        case let .bodyPartFileNotReachableWithError(url, error):            return """            The system returned an error while checking the provided URL for reachability.            URL: \(url)            Error: \(error)            """        case let .bodyPartFileIsDirectory(url):            return "The URL provided is a directory: \(url)"        case let .bodyPartFileSizeNotAvailable(url):            return "Could not fetch the file size from the provided URL: \(url)"        case let .bodyPartFileSizeQueryFailedWithError(url, error):            return """            The system returned an error while attempting to fetch the file size from the provided URL.            URL: \(url)            Error: \(error)            """        case let .bodyPartInputStreamCreationFailed(url):            return "Failed to create an InputStream for the provided URL: \(url)"        case let .outputStreamCreationFailed(url):            return "Failed to create an OutputStream for URL: \(url)"        case let .outputStreamFileAlreadyExists(url):            return "A file already exists at the provided URL: \(url)"        case let .outputStreamURLInvalid(url):            return "The provided OutputStream URL is invalid: \(url)"        case let .outputStreamWriteFailed(error):            return "OutputStream write failed with error: \(error)"        case let .inputStreamReadFailed(error):            return "InputStream read failed with error: \(error)"        }    }}extension AFError.ResponseSerializationFailureReason {    var localizedDescription: String {        switch self {        case .inputDataNilOrZeroLength:            return "Response could not be serialized, input data was nil or zero length."        case .inputFileNil:            return "Response could not be serialized, input file was nil."        case let .inputFileReadFailed(url):            return "Response could not be serialized, input file could not be read: \(url)."        case let .stringSerializationFailed(encoding):            return "String could not be serialized with encoding: \(encoding)."        case let .jsonSerializationFailed(error):            return "JSON could not be serialized because of error:\n\(error.localizedDescription)"        case let .invalidEmptyResponse(type):            return """            Empty response could not be serialized to type: \(type). \            Use Empty as the expected type for such responses.            """        case let .decodingFailed(error):            return "Response could not be decoded because of error:\n\(error.localizedDescription)"        case let .customSerializationFailed(error):            return "Custom response serializer failed with error:\n\(error.localizedDescription)"        }    }}extension AFError.ResponseValidationFailureReason {    var localizedDescription: String {        switch self {        case .dataFileNil:            return "Response could not be validated, data file was nil."        case let .dataFileReadFailed(url):            return "Response could not be validated, data file could not be read: \(url)."        case let .missingContentType(types):            return """            Response Content-Type was missing and acceptable content types \            (\(types.joined(separator: ","))) do not match "*/*".            """        case let .unacceptableContentType(acceptableTypes, responseType):            return """            Response Content-Type "\(responseType)" does not match any acceptable types: \            \(acceptableTypes.joined(separator: ",")).            """        case let .unacceptableStatusCode(code):            return "Response status code was unacceptable: \(code)."        case let .customValidationFailed(error):            return "Custom response validation failed with error: \(error.localizedDescription)"        }    }}extension AFError.ServerTrustFailureReason {    var localizedDescription: String {        switch self {        case let .noRequiredEvaluator(host):            return "A ServerTrustEvaluating value is required for host \(host) but none was found."        case .noCertificatesFound:            return "No certificates were found or provided for evaluation."        case .noPublicKeysFound:            return "No public keys were found or provided for evaluation."        case .policyApplicationFailed:            return "Attempting to set a SecPolicy failed."        case .settingAnchorCertificatesFailed:            return "Attempting to set the provided certificates as anchor certificates failed."        case .revocationPolicyCreationFailed:            return "Attempting to create a revocation policy failed."        case let .trustEvaluationFailed(error):            return "SecTrust evaluation failed with error: \(error?.localizedDescription ?? "None")"        case let .defaultEvaluationFailed(output):            return "Default evaluation failed for host \(output.host)."        case let .hostValidationFailed(output):            return "Host validation failed for host \(output.host)."        case let .revocationCheckFailed(output, _):            return "Revocation check failed for host \(output.host)."        case let .certificatePinningFailed(host, _, _, _):            return "Certificate pinning failed for host \(host)."        case let .publicKeyPinningFailed(host, _, _, _):            return "Public key pinning failed for host \(host)."        case let .customEvaluationFailed(error):            return "Custom trust evaluation failed with error: \(error.localizedDescription)"        }    }}extension AFError.URLRequestValidationFailureReason {    var localizedDescription: String {        switch self {        case let .bodyDataInGETRequest(data):            return """            Invalid URLRequest: Requests with GET method cannot have body data:            \(String(decoding: data, as: UTF8.self))            """        }    }}
 |