@@ -44,7 +44,7 @@ public struct Client {
4444throw . network( error)
4545}
4646guard let httpResponse= respas? HTTPURLResponse else {
47- throw . unexpectedResponse( data)
47+ throw . unexpectedResponse( String ( data: data , encoding : . utf8 ) ?? " <non-utf8 data> " )
4848}
4949return HTTPResponse ( resp: httpResponse, data: data, req: req)
5050}
@@ -72,7 +72,7 @@ public struct Client {
7272
7373func responseAsError( _ resp: HTTPResponse ) -> ClientError {
7474do {
75- let body = try Client . decoder . decode ( Response . self, from: resp. data)
75+ let body = try decode ( Response . self, from: resp. data)
7676let out = APIError (
7777 response: body,
7878 statusCode: resp. resp. statusCode,
@@ -81,7 +81,24 @@ public struct Client {
8181)
8282return . api( out)
8383} catch {
84- return . unexpectedResponse( resp. data. prefix ( 1024 ) )
84+ return . unexpectedResponse( String ( data: resp. data, encoding: . utf8) ?? " <non-utf8 data> " )
85+ }
86+ }
87+
88+ // Wrapper around JSONDecoder.decode that displays useful error messages from `DecodingError`.
89+ func decode< T> ( _: T . Type , from data: Data ) throws ( ClientError) -> T where T: Decodable {
90+ do {
91+ return try Client . decoder. decode ( T . self, from: data)
92+ } catch let DecodingError . keyNotFound( _, context) {
93+ throw . unexpectedResponse( " Key not found: \( context. debugDescription) " )
94+ } catch let DecodingError . valueNotFound( _, context) {
95+ throw . unexpectedResponse( " Value not found: \( context. debugDescription) " )
96+ } catch let DecodingError . typeMismatch( _, context) {
97+ throw . unexpectedResponse( " Type mismatch: \( context. debugDescription) " )
98+ } catch let DecodingError . dataCorrupted( context) {
99+ throw . unexpectedResponse( " Data corrupted: \( context. debugDescription) " )
100+ } catch {
101+ throw . unexpectedResponse( String ( data: data. prefix ( 1024 ) , encoding: . utf8) ?? " <non-utf8 data> " )
85102}
86103}
87104}
@@ -119,7 +136,7 @@ public struct FieldValidation: Decodable, Sendable {
119136public enum ClientError : Error {
120137case api( APIError )
121138case network( any Error )
122- case unexpectedResponse( Data )
139+ case unexpectedResponse( String )
123140case encodeFailure( any Error )
124141
125142public var description : String {
@@ -129,7 +146,7 @@ public enum ClientError: Error {
129146case let . network( error) :
130147 error. localizedDescription
131148case let . unexpectedResponse( data) :
132- " Unexpectedor non HTTP response: \( data) "
149+ " Unexpected response: \( data) "
133150case let . encodeFailure( error) :
134151" Failed to encode body: \( error. localizedDescription) "
135152}