Skip to content

Commit 23b1989

Browse files
refactor: consistent error handling (#792)
* Replace custom PrefixedString error with DecodingError * Replace InsightsEvent.Resources.Error with DecodingFailure error * Make ObjectIDChecker and ObjectIDChecker.Error public * Make SwitchHostError and BodyAPIKeyError public
1 parent bf0c901 commit 23b1989

33 files changed

+403
-271
lines changed

Sources/AlgoliaSearchClient/Client/AccountClient.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ public struct AccountClient {
8989

9090
}
9191

92-
extension AccountClient {
92+
public extension AccountClient {
9393

94-
public enum Error: Swift.Error {
94+
enum Error: Swift.Error {
9595
case sourceNotFound
9696
case existingDestination
9797
case sameApplicationID

Sources/AlgoliaSearchClient/Command/Command+Custom.swift

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,18 @@ extension Command {
3636
urlRequest: URLRequest,
3737
requestOptions: RequestOptions?) throws {
3838
self.callType = callType
39-
guard let method = urlRequest.httpMethod.flatMap(HTTPMethod.init(rawValue:)) else {
40-
throw AlgoliaCommandError.invalidHTTPMethod
39+
self.method = urlRequest.httpMethod.flatMap(HTTPMethod.init(rawValue:)) ?? .get
40+
guard let url = urlRequest.url else {
41+
throw URLRequest.FormatError.missingURL
4142
}
42-
self.method = method
43-
guard let path = urlRequest.url?.path, let pathURL = URL(string: path) else {
44-
throw AlgoliaCommandError.invalidPath
43+
guard let pathURL = URL(string: url.path) else {
44+
throw URLRequest.FormatError.invalidPath(url.path)
4545
}
4646
self.path = pathURL
4747
self.body = urlRequest.httpBody
4848
self.requestOptions = requestOptions
4949
}
5050

51-
enum AlgoliaCommandError: Error {
52-
case invalidHTTPMethod
53-
case invalidPath
54-
}
5551
}
5652

5753
}

Sources/AlgoliaSearchClient/Helpers/ObjectIDChecker.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import Foundation
99

10-
struct ObjectIDChecker {
10+
public struct ObjectIDChecker {
1111

1212
static func checkObjectID<T: Encodable>(_ object: T) throws {
1313
let data = try JSONEncoder().encode(object)
@@ -26,7 +26,7 @@ struct ObjectIDChecker {
2626
}
2727
}
2828

29-
enum Error: Swift.Error {
29+
public enum Error: Swift.Error {
3030
case missingObjectIDProperty
3131

3232
var localizedDescription: String {

Sources/AlgoliaSearchClient/Index/Index+Index.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,13 @@ public extension Index {
6767
switch result {
6868
case .success:
6969
return true
70-
case .failure(let error) where (error as? HTTPError)?.statusCode == .notFound:
71-
return false
7270
case .failure(let error):
73-
throw error
71+
switch error {
72+
case TransportError.httpError(let httpError) where httpError.statusCode == .notFound:
73+
return false
74+
default:
75+
throw error
76+
}
7477
}
7578
}
7679

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// CompositeError.swift
3+
//
4+
//
5+
// Created by Vladislav Fitc on 21/07/2022.
6+
//
7+
8+
import Foundation
9+
10+
public struct CompositeError: Error {
11+
12+
public let errors: [Error]
13+
14+
public init(errors: [Error]) {
15+
self.errors = errors
16+
}
17+
18+
public static func with(_ errors: Error...) -> Self {
19+
CompositeError(errors: errors)
20+
}
21+
22+
}

Sources/AlgoliaSearchClient/Models/Data structures/PrefixedString.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct PrefixedString: CustomStringConvertible, Codable {
3131
if let prefixedString = PrefixedString(rawValue: rawValue) {
3232
self = prefixedString
3333
} else {
34-
throw Error.wrongFormat
34+
throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "\(rawValue) doesn't match the `prefix(value)` format"))
3535
}
3636
}
3737

@@ -44,10 +44,6 @@ struct PrefixedString: CustomStringConvertible, Codable {
4444
return "\(prefix)(\(value))"
4545
}
4646

47-
enum Error: Swift.Error {
48-
case wrongFormat
49-
}
50-
5147
}
5248

5349
extension PrefixedString {

Sources/AlgoliaSearchClient/Models/Insights/EventConstructionError.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77

88
import Foundation
99

10-
extension InsightsEvent {
10+
public extension InsightsEvent {
1111

12-
public enum Constraints {
12+
enum Constraints {
1313
public static let maxObjectIDsCount = 20
1414
public static let maxFiltersCount = 10
1515
}
1616

17-
public enum ConstructionError: Error {
17+
enum ConstructionError: Error {
1818

1919
case emptyEventName
2020
case objectIDsCountOverflow

Sources/AlgoliaSearchClient/Models/Insights/InsightsEvent+Resources.swift

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,35 @@ extension InsightsEvent.Resources: Codable {
4343

4444
let container = try decoder.container(keyedBy: CodingKeys.self)
4545

46-
if let objectIDs = try? container.decode([ObjectID].self, forKey: .objectIDs) {
46+
let objectIDsDecodingError: Error
47+
let filtersDecodingError: Error
48+
49+
do {
50+
let objectIDs = try container.decode([ObjectID].self, forKey: .objectIDs)
4751
if let positions = try? container.decode([Int].self, forKey: .positions) {
4852
self = .objectIDsWithPositions(zip(objectIDs, positions).map { $0 })
4953
} else {
5054
self = .objectIDs(objectIDs)
5155
}
52-
} else if let filters = try? container.decode([String].self, forKey: .filters) {
56+
return
57+
} catch let error {
58+
objectIDsDecodingError = error
59+
}
60+
61+
do {
62+
let filters = try container.decode([String].self, forKey: .filters)
5363
self = .filters(filters)
54-
} else {
55-
throw Error.decodingFailure
64+
return
65+
} catch let error {
66+
filtersDecodingError = error
5667
}
5768

69+
let compositeError = CompositeError.with(objectIDsDecodingError, filtersDecodingError)
70+
typealias Keys = InsightsEvent.Resources.CodingKeys
71+
let context = DecodingError.Context(codingPath: decoder.codingPath,
72+
debugDescription: "Neither \(Keys.filters.rawValue), nor \(Keys.objectIDs.rawValue) key found on decoder",
73+
underlyingError: compositeError)
74+
throw DecodingError.dataCorrupted(context)
5875
}
5976

6077
public func encode(to encoder: Encoder) throws {
@@ -76,22 +93,3 @@ extension InsightsEvent.Resources: Codable {
7693
}
7794

7895
}
79-
80-
public extension InsightsEvent.Resources {
81-
82-
enum Error: Swift.Error {
83-
case decodingFailure
84-
}
85-
86-
}
87-
88-
extension InsightsEvent.Resources.Error: LocalizedError {
89-
90-
public var errorDescription: String? {
91-
switch self {
92-
case .decodingFailure:
93-
return "Neither \(InsightsEvent.Resources.CodingKeys.filters.rawValue), nor \(InsightsEvent.Resources.CodingKeys.objectIDs.rawValue) key found on decoder"
94-
}
95-
}
96-
97-
}

Sources/AlgoliaSearchClient/Models/Search/Indexing/Scope.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extension Scope {
5151

5252
}
5353

54-
public struct ScopeComponent: StringOption & ProvidingCustomOption {
54+
public struct ScopeComponent: StringOption, ProvidingCustomOption {
5555

5656
public let rawValue: String
5757

Sources/AlgoliaSearchClient/Models/Search/Query/Auxiliary/Point.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ extension Point: Codable {
8888
self = stringForm.point
8989
} else {
9090
let encoded = (try? String(data: JSONEncoder().encode(JSON(from: decoder)), encoding: .utf8)) ?? ""
91-
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "The format \(encoded) doesn't match \"22.2268,84.8463\" string or {\"lat\": 22.2268, \"lng\": 84.8463 } dictionary"))
91+
let context = DecodingError.Context(codingPath: decoder.codingPath,
92+
debugDescription: "The format \(encoded) doesn't match \"22.2268,84.8463\" string or {\"lat\": 22.2268, \"lng\": 84.8463 } dictionary")
93+
throw DecodingError.dataCorrupted(context)
9294
}
9395
}
9496

0 commit comments

Comments
 (0)