@@ -27,41 +27,144 @@ import FoundationNetworking
2727
2828/// Errors thrown when executing REST requests.
2929///
30- /// Every case carries additional context so that callers can decide whether to retry, surface the failure,
31- /// or attempt to recover (for example when a deserializer reports malformed data).
30+ /// `RestError` provides comprehensive error information for REST API operations, allowing callers to
31+ /// make informed decisions about error handling, retry strategies, and recovery options.
32+ ///
33+ /// ## Overview
34+ /// This error type encapsulates various failure scenarios that can occur during REST API interactions:
35+ /// - Invalid response formats or protocols
36+ /// - Unexpected MIME types
37+ /// - Query parameter encoding issues
38+ /// - Response deserialization failures
39+ /// - HTTP status code violations
40+ /// - Server-reported errors
41+ ///
42+ /// ## Topics
43+ ///
44+ /// ### Response Validation Errors
45+ /// - ``badResponse(_:_:)``
46+ /// - ``invalidMimeType(_:)``
47+ /// - ``unexpectedHttpStatusCode(_:)``
48+ ///
49+ /// ### Data Processing Errors
50+ /// - ``malformedResponse(_:_:_:)``
51+ /// - ``invalidQueryParameter``
52+ ///
53+ /// ### API Errors
54+ /// - ``failedRestCall(_:_:error:)``
55+ ///
56+ /// ## Usage Example
57+ /// ```swift
58+ /// do {
59+ /// let result = try await restClient.get("https://api.example.com/data")
60+ /// } catch let error as RestError {
61+ /// switch error {
62+ /// case .invalidMimeType(let mime):
63+ /// print("Unexpected content type: \(mime ?? "none")")
64+ /// case .failedRestCall(_, let status, let error):
65+ /// print("API error: \(status), details: \(error ?? "none")")
66+ /// case .malformedResponse(_, _, let error):
67+ /// print("Failed to parse response: \(error)")
68+ /// // Handle other cases...
69+ /// }
70+ /// }
71+ /// ```
3272public enum RestError : Error {
3373
34- /// Indicates that the server responded using an unknown protocol.
74+ /// Indicates that the server responded using an unknown or unsupported protocol.
75+ ///
76+ /// This error occurs when the server's response doesn't conform to the expected HTTP/HTTPS protocol
77+ /// or when the response format is invalid.
78+ ///
3579 /// - Parameters:
36- /// - URLResponse: The response returned form the server.
37- /// - Data: The raw returned data from the server.
80+ /// - URLResponse: The raw response returned from the server.
81+ /// - Data: The raw data returned in the response body.
82+ ///
83+ /// - Note: This error typically indicates a server misconfiguration or a proxy interference.
3884 case badResponse( URLResponse , Data )
3985
4086 /// Indicates that the server responded with an unexpected MIME type.
41- /// - Parameter String: The returned MIME type.
87+ ///
88+ /// This error occurs when the Content-Type header in the response doesn't match
89+ /// the expected MIME type for the request. For example, receiving "text/plain"
90+ /// when "application/json" was expected.
91+ ///
92+ /// - Parameter String: The MIME type received in the response's Content-Type header.
93+ /// May be nil if no Content-Type header was present.
94+ ///
95+ /// - Note: Configure `RestOptions.acceptedMimeTypes` to specify additional accepted MIME types.
4296 case invalidMimeType( String ? )
4397
44- /// Indicates that query parameters with key could not be encoded using percent encoding.
98+ /// Indicates that query parameters could not be encoded using percent encoding.
99+ ///
100+ /// This error occurs when attempting to encode query parameters into a URL-safe format
101+ /// using percent encoding, but the encoding operation fails. This typically happens when
102+ /// parameter values contain characters that cannot be safely encoded for URL transmission.
103+ ///
104+ /// - Note: To avoid this error, ensure query parameters contain only URL-safe characters
105+ /// or properly encode special characters before making the request.
45106 case invalidQueryParameter
46107
47108 /// Indicates the server's response could not be deserialized using the given Deserializer.
109+ ///
110+ /// This error occurs when the response data cannot be converted into the expected type
111+ /// using the configured Deserializer. Common causes include:
112+ /// - Mismatched data structure
113+ /// - Missing required fields
114+ /// - Invalid data types
115+ /// - Malformed JSON or other formats
116+ ///
48117 /// - Parameters:
49- /// - HTTPURLResponse: The HTTPURLResponse from the server.
50- /// - Data: The raw returned data from the server.
51- /// - Error: The original system error (like a `DecodingError`) that triggered the failure.
118+ /// - HTTPURLResponse: The HTTP response metadata from the server.
119+ /// - Data: The raw response data that failed to deserialize.
120+ /// - Error: The underlying error (typically a `DecodingError`) that provides
121+ /// specific details about why deserialization failed.
122+ ///
123+ /// - Note: Inspect the underlying Error for detailed information about the deserialization failure.
124+ /// For DecodingError cases, the error will contain the specific path where decoding failed.
52125 case malformedResponse( HTTPURLResponse , Data , Error )
53126
54- /// Indicates the API call failed and optionally surfaces the parsed error payload.
127+ /// Indicates the API call failed with an error response from the server.
128+ ///
129+ /// This error represents a failed API call where the server returned an error response.
130+ /// The error includes the full HTTP response, the specific status code, and optionally
131+ /// a parsed error payload from the response body.
132+ ///
55133 /// - Parameters:
56- /// - HTTPURLResponse: The HTTPURLResponse from the server.
57- /// - HTTPStatusCode: The returned HTTP status.
58- /// - error: The deserialized error payload, if available.
134+ /// - HTTPURLResponse: The complete HTTP response containing headers and metadata.
135+ /// - HTTPStatusCode: The specific HTTP status code indicating the type of failure.
136+ /// - error: The deserialized error payload from the response body, if one was
137+ /// provided and could be parsed. The error payload must conform to `Sendable`.
138+ ///
139+ /// ## Example
140+ /// ```swift
141+ /// catch case let RestError.failedRestCall(response, status, error) {
142+ /// print("API call failed with status: \(status)")
143+ /// if let apiError = error as? MyAPIError {
144+ /// print("Error details: \(apiError)")
145+ /// }
146+ /// }
147+ /// ```
59148 case failedRestCall( HTTPURLResponse , HTTPStatusCode , error: ( any Sendable ) ? )
60149
61150 /// Indicates that the response contained an unexpected HTTP status code.
62151 ///
63- /// Configure `RestOptions.expectedStatusCodes` to mark additional status codes as valid.
64- /// - Parameter Int: The HTTP status returned from the server.
152+ /// This error occurs when the server returns an HTTP status code that isn't in the
153+ /// set of expected status codes for the request. By default, only 2xx status codes
154+ /// are considered valid.
155+ ///
156+ /// - Parameter Int: The unexpected HTTP status code returned from the server.
157+ ///
158+ /// - Note: You can configure additional valid status codes using `RestOptions.expectedStatusCodes`.
159+ /// This is useful when certain error codes should be treated as valid responses
160+ /// for your specific use case.
161+ ///
162+ /// ## Example
163+ /// ```swift
164+ /// // Configure 404 as valid for this request
165+ /// var options = RestOptions()
166+ /// options.expectedStatusCodes = [200, 404]
167+ /// ```
65168 case unexpectedHttpStatusCode( Int )
66169
67170}
0 commit comments