Skip to content

Commit 914e8c7

Browse files
committed
use jsonapi type names instead of indices in include decode failure messages.
1 parent 1ec7913 commit 914e8c7

6 files changed

Lines changed: 80 additions & 53 deletions

File tree

Sources/JSONAPI/Document/Includes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ public struct IncludeDecodingError: Swift.Error, Equatable, CustomStringConverti
254254
return failures
255255
.enumerated()
256256
.map {
257-
"\nCould not have been Include Type \($0.offset + 1) because:\n\($0.element)"
257+
"\nCould not have been Include Type `\($0.element.resourceObjectJsonAPIType)` because:\n\($0.element)"
258258
}.joined(separator: "\n")
259259
}
260260
}

Sources/JSONAPI/Resource/Resource Object/ResourceObject.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ public extension ResourceObject {
398398
do {
399399
type = try container.decode(String.self, forKey: .type)
400400
} catch let error as DecodingError {
401-
throw ResourceObjectDecodingError(error)
401+
throw ResourceObjectDecodingError(error, jsonAPIType: Self.jsonType)
402402
?? error
403403
}
404404

@@ -417,13 +417,14 @@ public extension ResourceObject {
417417
?? container.decodeIfPresent(Description.Attributes.self, forKey: .attributes)
418418
?? Description.Attributes(from: EmptyObjectDecoder())
419419
} catch let decodingError as DecodingError {
420-
throw ResourceObjectDecodingError(decodingError)
420+
throw ResourceObjectDecodingError(decodingError, jsonAPIType: Self.jsonType)
421421
?? decodingError
422422
} catch _ as EmptyObjectDecodingError {
423423
throw ResourceObjectDecodingError(
424424
subjectName: ResourceObjectDecodingError.entireObject,
425425
cause: .keyNotFound,
426-
location: .attributes
426+
location: .attributes,
427+
jsonAPIType: Self.jsonType
427428
)
428429
}
429430

@@ -432,16 +433,17 @@ public extension ResourceObject {
432433
?? container.decodeIfPresent(Description.Relationships.self, forKey: .relationships)
433434
?? Description.Relationships(from: EmptyObjectDecoder())
434435
} catch let decodingError as DecodingError {
435-
throw ResourceObjectDecodingError(decodingError)
436+
throw ResourceObjectDecodingError(decodingError, jsonAPIType: Self.jsonType)
436437
?? decodingError
437438
} catch let decodingError as JSONAPICodingError {
438-
throw ResourceObjectDecodingError(decodingError)
439+
throw ResourceObjectDecodingError(decodingError, jsonAPIType: Self.jsonType)
439440
?? decodingError
440441
} catch _ as EmptyObjectDecodingError {
441442
throw ResourceObjectDecodingError(
442443
subjectName: ResourceObjectDecodingError.entireObject,
443444
cause: .keyNotFound,
444-
location: .relationships
445+
location: .relationships,
446+
jsonAPIType: Self.jsonType
445447
)
446448
}
447449

Sources/JSONAPI/Resource/Resource Object/ResourceObjectDecodingError.swift

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77

88
public struct ResourceObjectDecodingError: Swift.Error, Equatable {
9+
public let resourceObjectJsonAPIType: String
910
public let subjectName: String
1011
public let cause: Cause
1112
public let location: Location
@@ -16,7 +17,7 @@ public struct ResourceObjectDecodingError: Swift.Error, Equatable {
1617
case keyNotFound
1718
case valueNotFound
1819
case typeMismatch(expectedTypeName: String)
19-
case jsonTypeMismatch(expectedType: String, foundType: String)
20+
case jsonTypeMismatch(foundType: String)
2021
case quantityMismatch(expected: JSONAPICodingError.Quantity)
2122
}
2223

@@ -38,7 +39,8 @@ public struct ResourceObjectDecodingError: Swift.Error, Equatable {
3839
}
3940
}
4041

41-
init?(_ decodingError: DecodingError) {
42+
init?(_ decodingError: DecodingError, jsonAPIType: String) {
43+
self.resourceObjectJsonAPIType = jsonAPIType
4244
switch decodingError {
4345
case .typeMismatch(let expectedType, let ctx):
4446
(location, subjectName) = Self.context(ctx)
@@ -67,11 +69,12 @@ public struct ResourceObjectDecodingError: Swift.Error, Equatable {
6769
}
6870
}
6971

70-
init?(_ jsonAPIError: JSONAPICodingError) {
72+
init?(_ jsonAPIError: JSONAPICodingError, jsonAPIType: String) {
73+
self.resourceObjectJsonAPIType = jsonAPIType
7174
switch jsonAPIError {
7275
case .typeMismatch(expected: let expected, found: let found, path: let path):
7376
(location, subjectName) = Self.context(path: path)
74-
cause = .jsonTypeMismatch(expectedType: expected, foundType: found)
77+
cause = .jsonTypeMismatch(foundType: found)
7578
case .quantityMismatch(expected: let expected, path: let path):
7679
(location, subjectName) = Self.context(path: path)
7780
cause = .quantityMismatch(expected: expected)
@@ -81,12 +84,14 @@ public struct ResourceObjectDecodingError: Swift.Error, Equatable {
8184
}
8285

8386
init(expectedJSONAPIType: String, found: String) {
87+
resourceObjectJsonAPIType = expectedJSONAPIType
8488
location = .type
8589
subjectName = "self"
86-
cause = .jsonTypeMismatch(expectedType: expectedJSONAPIType, foundType: found)
90+
cause = .jsonTypeMismatch(foundType: found)
8791
}
8892

89-
init(subjectName: String, cause: Cause, location: Location) {
93+
init(subjectName: String, cause: Cause, location: Location, jsonAPIType: String) {
94+
self.resourceObjectJsonAPIType = jsonAPIType
9095
self.subjectName = subjectName
9196
self.cause = cause
9297
self.location = location
@@ -135,10 +140,10 @@ extension ResourceObjectDecodingError: CustomStringConvertible {
135140
return "'\(location.singular)' (a.k.a. the JSON:API type name) is not a \(expected) as expected."
136141
case .typeMismatch(expectedTypeName: let expected):
137142
return "'\(subjectName)' \(location.singular) is not a \(expected) as expected."
138-
case .jsonTypeMismatch(expectedType: let expected, foundType: let found) where location == .type:
139-
return "found JSON:API type \"\(found)\" but expected \"\(expected)\""
140-
case .jsonTypeMismatch(expectedType: let expected, foundType: let found):
141-
return "'\(subjectName)' \(location.singular) is of JSON:API type \"\(found)\" but it was expected to be \"\(expected)\""
143+
case .jsonTypeMismatch(foundType: let found) where location == .type:
144+
return "found JSON:API type \"\(found)\" but expected \"\(resourceObjectJsonAPIType)\""
145+
case .jsonTypeMismatch(foundType: let found):
146+
return "'\(subjectName)' \(location.singular) is of JSON:API type \"\(found)\" but it was expected to be \"\(resourceObjectJsonAPIType)\""
142147
case .quantityMismatch(expected: let expected):
143148
let expecation: String = {
144149
switch expected {

Tests/JSONAPITests/Document/DocumentDecodingErrorTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,10 @@ final class DocumentDecodingErrorTests: XCTestCase {
114114
String(describing: error),
115115
#"""
116116
Out of 3 includes, the 3rd one failed to parse:
117-
Could not have been Include Type 1 because:
117+
Could not have been Include Type `articles` because:
118118
found JSON:API type "not_an_author" but expected "articles"
119119
120-
Could not have been Include Type 2 because:
120+
Could not have been Include Type `authors` because:
121121
found JSON:API type "not_an_author" but expected "authors"
122122
"""#
123123
)
@@ -142,10 +142,10 @@ final class DocumentDecodingErrorTests: XCTestCase {
142142
String(describing: error),
143143
#"""
144144
Out of 3 includes, the 2nd one failed to parse:
145-
Could not have been Include Type 1 because:
145+
Could not have been Include Type `articles` because:
146146
found JSON:API type "not_an_author" but expected "articles"
147147
148-
Could not have been Include Type 2 because:
148+
Could not have been Include Type `authors` because:
149149
found JSON:API type "not_an_author" but expected "authors"
150150
"""#
151151
)

Tests/JSONAPITests/Includes/IncludesDecodingErrorTests.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ final class IncludesDecodingErrorTests: XCTestCase {
1919
XCTAssertEqual(
2020
(error as? IncludesDecodingError).map(String.init(describing:)),
2121
"""
22-
Out of 3 includes, the 3rd one failed to parse: \nCould not have been Include Type 1 because:
22+
Out of 3 includes, the 3rd one failed to parse: \nCould not have been Include Type `test_entity1` because:
2323
found JSON:API type "test_entity4" but expected "test_entity1"
2424
25-
Could not have been Include Type 2 because:
25+
Could not have been Include Type `test_entity2` because:
2626
found JSON:API type "test_entity4" but expected "test_entity2"
2727
"""
2828
)
@@ -33,10 +33,10 @@ final class IncludesDecodingErrorTests: XCTestCase {
3333
XCTAssertEqual(
3434
(error2 as? IncludesDecodingError).map(String.init(describing:)),
3535
"""
36-
Out of 4 includes, the 3rd one failed to parse: \nCould not have been Include Type 1 because:
36+
Out of 4 includes, the 3rd one failed to parse: \nCould not have been Include Type `test_entity1` because:
3737
found JSON:API type "test_entity4" but expected "test_entity1"
3838
39-
Could not have been Include Type 2 because:
39+
Could not have been Include Type `test_entity2` because:
4040
found JSON:API type "test_entity4" but expected "test_entity2"
4141
"""
4242
)
@@ -47,10 +47,10 @@ final class IncludesDecodingErrorTests: XCTestCase {
4747
XCTAssertEqual(
4848
(error2 as? IncludesDecodingError).map(String.init(describing:)),
4949
"""
50-
Out of 6 includes, the 5th one failed to parse: \nCould not have been Include Type 1 because:
50+
Out of 6 includes, the 5th one failed to parse: \nCould not have been Include Type `test_entity1` because:
5151
found JSON:API type "test_entity4" but expected "test_entity1"
5252
53-
Could not have been Include Type 2 because:
53+
Could not have been Include Type `test_entity2` because:
5454
found JSON:API type "test_entity4" but expected "test_entity2"
5555
"""
5656
)
@@ -61,10 +61,10 @@ final class IncludesDecodingErrorTests: XCTestCase {
6161
XCTAssertEqual(
6262
(error2 as? IncludesDecodingError).map(String.init(describing:)),
6363
"""
64-
Out of 11 includes, the 10th one failed to parse: \nCould not have been Include Type 1 because:
64+
Out of 11 includes, the 10th one failed to parse: \nCould not have been Include Type `test_entity1` because:
6565
found JSON:API type "test_entity4" but expected "test_entity1"
6666
67-
Could not have been Include Type 2 because:
67+
Could not have been Include Type `test_entity2` because:
6868
found JSON:API type "test_entity4" but expected "test_entity2"
6969
"""
7070
)
@@ -75,10 +75,10 @@ final class IncludesDecodingErrorTests: XCTestCase {
7575
XCTAssertEqual(
7676
(error2 as? IncludesDecodingError).map(String.init(describing:)),
7777
"""
78-
Out of 22 includes, the 21st one failed to parse: \nCould not have been Include Type 1 because:
78+
Out of 22 includes, the 21st one failed to parse: \nCould not have been Include Type `test_entity1` because:
7979
found JSON:API type "test_entity4" but expected "test_entity1"
8080
81-
Could not have been Include Type 2 because:
81+
Could not have been Include Type `test_entity2` because:
8282
found JSON:API type "test_entity4" but expected "test_entity2"
8383
"""
8484
)

0 commit comments

Comments
 (0)