Skip to content

Commit deeae68

Browse files
author
Nilanshu Sharma
committed
Addressing PR comments
Signed-off-by: Nilanshu Sharma <nilanshu_sharma@apple.com>
1 parent 28496ed commit deeae68

File tree

2 files changed

+42
-57
lines changed

2 files changed

+42
-57
lines changed

Sources/Valkey/Commands/Custom/ClusterCustomCommands.swift

Lines changed: 30 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,6 @@ package struct ValkeyClusterParseError: Error, Equatable {
4747
case missingRequiredValueForNode
4848
case shardIsMissingHashSlots
4949
case shardIsMissingNode
50-
case clusterLinksTokenIsNotAnArray
51-
case clusterLinkTokenIsNotAnArrayOrMap
52-
case missingRequiredValueForLink
53-
case invalidLinkDirection
54-
case clusterSlotStatsTokenIsNotAnArray
55-
case clusterSlotStatsTokenIsNotAnArrayOrMap
56-
case missingRequiredValueForSlotStats
57-
case clusterSlotsTokenIsNotAnArray
58-
case clusterSlotRangeTokenIsNotAnArray
59-
case clusterSlotNodeTokenIsNotAnArray
60-
case missingRequiredValueForSlotRange
61-
case missingRequiredValueForSlotNode
62-
case clusterSlotNodeMetadataIsNotAnArrayOrMap
6350
}
6451

6552
package var reason: Reason
@@ -305,11 +292,7 @@ public struct ValkeyClusterLink: Hashable, Sendable, RESPTokenDecodable {
305292
/// Creates a cluster link from the response token you provide.
306293
/// - Parameter respToken: The response token.
307294
public init(fromRESP respToken: RESPToken) throws {
308-
do {
309-
self = try Self.makeClusterLink(respToken: respToken)
310-
} catch {
311-
throw ValkeyClusterParseError(reason: error, token: respToken)
312-
}
295+
self = try Self.makeClusterLink(respToken: respToken)
313296
}
314297
}
315298

@@ -352,11 +335,7 @@ public struct ValkeyClusterSlotStats: Hashable, Sendable, RESPTokenDecodable {
352335
/// Creates a cluster slot stats from the response token you provide.
353336
/// - Parameter respToken: The response token.
354337
public init(fromRESP respToken: RESPToken) throws {
355-
do {
356-
self = try Self.makeClusterSlotStats(respToken: respToken)
357-
} catch {
358-
throw ValkeyClusterParseError(reason: error, token: respToken)
359-
}
338+
self = try Self.makeClusterSlotStats(respToken: respToken)
360339
}
361340
}
362341

@@ -415,11 +394,7 @@ public struct ValkeyClusterSlotRange: Hashable, Sendable, RESPTokenDecodable {
415394
/// Creates a cluster slot range from the response token you provide.
416395
/// - Parameter respToken: The response token.
417396
public init(fromRESP respToken: RESPToken) throws {
418-
do {
419-
self = try Self.makeClusterSlotRange(respToken: respToken)
420-
} catch {
421-
throw ValkeyClusterParseError(reason: error, token: respToken)
422-
}
397+
self = try Self.makeClusterSlotRange(respToken: respToken)
423398
}
424399
}
425400

@@ -627,10 +602,10 @@ extension ValkeyClusterDescription.Node {
627602
}
628603

629604
extension ValkeyClusterLink {
630-
fileprivate static func makeClusterLink(respToken: RESPToken) throws(ValkeyClusterParseError.Reason) -> ValkeyClusterLink {
605+
fileprivate static func makeClusterLink(respToken: RESPToken) throws(RESPDecodeError) -> ValkeyClusterLink {
631606
switch respToken.value {
632607
case .array(let array):
633-
return try Self.makeFromTokenSequence(MapStyleArray(underlying: array))
608+
return try Self.makeFromTokenSequence(MapStyleArray(underlying: array), respToken)
634609

635610
case .map(let map):
636611
let mapped = map.lazy.compactMap { (keyNode, value) -> (String, RESPToken)? in
@@ -640,16 +615,17 @@ extension ValkeyClusterLink {
640615
return nil
641616
}
642617
}
643-
return try Self.makeFromTokenSequence(mapped)
618+
return try Self.makeFromTokenSequence(mapped, respToken)
644619

645620
default:
646-
throw .clusterLinkTokenIsNotAnArrayOrMap
621+
throw RESPDecodeError.tokenMismatch(expected: [.array, .map], token: respToken)
647622
}
648623
}
649624

650625
fileprivate static func makeFromTokenSequence<TokenSequence: Sequence>(
651-
_ sequence: TokenSequence
652-
) throws(ValkeyClusterParseError.Reason) -> Self where TokenSequence.Element == (String, RESPToken) {
626+
_ sequence: TokenSequence,
627+
_ respToken: RESPToken
628+
) throws(RESPDecodeError) -> Self where TokenSequence.Element == (String, RESPToken) {
653629
var direction: ValkeyClusterLink.Direction?
654630
var node: String?
655631
var createTime: Int64?
@@ -663,7 +639,7 @@ extension ValkeyClusterLink {
663639
guard let directionString = try? String(fromRESP: value),
664640
let directionValue = ValkeyClusterLink.Direction(rawValue: directionString)
665641
else {
666-
throw .invalidLinkDirection
642+
throw RESPDecodeError.missingToken(key: "direction", token: respToken)
667643
}
668644
direction = directionValue
669645

@@ -700,13 +676,13 @@ extension ValkeyClusterLink {
700676
}
701677

702678
extension ValkeyClusterSlotStats {
703-
fileprivate static func makeClusterSlotStats(respToken: RESPToken) throws(ValkeyClusterParseError.Reason) -> ValkeyClusterSlotStats {
679+
fileprivate static func makeClusterSlotStats(respToken: RESPToken) throws(RESPDecodeError) -> ValkeyClusterSlotStats {
704680
guard case .array(let array) = respToken.value else {
705-
throw .clusterSlotStatsTokenIsNotAnArray
681+
throw RESPDecodeError.tokenMismatch(expected: [.array], token: respToken)
706682
}
707683

708684
guard array.count >= 2 else {
709-
throw .missingRequiredValueForSlotStats
685+
throw RESPDecodeError.invalidArraySize(array, minExpectedSize: 2)
710686
}
711687

712688
var iterator = array.makeIterator()
@@ -715,18 +691,18 @@ extension ValkeyClusterSlotStats {
715691
guard let slotToken = iterator.next(),
716692
case .number(let slotNumber) = slotToken.value
717693
else {
718-
throw .missingRequiredValueForSlotStats
694+
throw RESPDecodeError.missingToken(key: "slot", token: respToken)
719695
}
720696

721697
// Second element: statistics map
722698
guard let statsToken = iterator.next() else {
723-
throw .missingRequiredValueForSlotStats
699+
throw RESPDecodeError.missingToken(key: "statistics", token: respToken)
724700
}
725701

726702
return try Self.makeFromStatsToken(slot: Int(slotNumber), statsToken: statsToken)
727703
}
728704

729-
fileprivate static func makeFromStatsToken(slot: Int, statsToken: RESPToken) throws(ValkeyClusterParseError.Reason) -> Self {
705+
fileprivate static func makeFromStatsToken(slot: Int, statsToken: RESPToken) throws(RESPDecodeError) -> Self {
730706
var keyCount: Int64?
731707
var cpuUsec: Int64?
732708
var networkBytesIn: Int64?
@@ -786,7 +762,7 @@ extension ValkeyClusterSlotStats {
786762
}
787763

788764
default:
789-
throw .clusterSlotStatsTokenIsNotAnArrayOrMap
765+
throw RESPDecodeError.tokenMismatch(expected: [.array, .map], token: statsToken)
790766
}
791767

792768
return ValkeyClusterSlotStats(
@@ -800,13 +776,13 @@ extension ValkeyClusterSlotStats {
800776
}
801777

802778
extension ValkeyClusterSlotRange {
803-
fileprivate static func makeClusterSlotRange(respToken: RESPToken) throws(ValkeyClusterParseError.Reason) -> ValkeyClusterSlotRange {
779+
fileprivate static func makeClusterSlotRange(respToken: RESPToken) throws(RESPDecodeError) -> ValkeyClusterSlotRange {
804780
guard case .array(let array) = respToken.value else {
805-
throw .clusterSlotRangeTokenIsNotAnArray
781+
throw RESPDecodeError.tokenMismatch(expected: [.array], token: respToken)
806782
}
807783

808784
guard array.count >= 3 else {
809-
throw .missingRequiredValueForSlotRange
785+
throw RESPDecodeError.invalidArraySize(array, minExpectedSize: 3)
810786
}
811787

812788
var iterator = array.makeIterator()
@@ -815,14 +791,14 @@ extension ValkeyClusterSlotRange {
815791
guard let startSlotToken = iterator.next(),
816792
case .number(let startSlotNumber) = startSlotToken.value
817793
else {
818-
throw .missingRequiredValueForSlotRange
794+
throw RESPDecodeError.missingToken(key: "start slot", token: respToken)
819795
}
820796

821797
// Second element: end slot
822798
guard let endSlotToken = iterator.next(),
823799
case .number(let endSlotNumber) = endSlotToken.value
824800
else {
825-
throw .missingRequiredValueForSlotRange
801+
throw RESPDecodeError.missingToken(key: "end slot", token: respToken)
826802
}
827803

828804
let startSlot = Int(startSlotNumber)
@@ -844,14 +820,14 @@ extension ValkeyClusterSlotRange {
844820
}
845821

846822
extension ValkeyClusterSlotRange.Node {
847-
fileprivate static func makeSlotNode(respToken: RESPToken) throws(ValkeyClusterParseError.Reason) -> ValkeyClusterSlotRange.Node {
823+
fileprivate static func makeSlotNode(respToken: RESPToken) throws(RESPDecodeError) -> ValkeyClusterSlotRange.Node {
848824
guard case .array(let array) = respToken.value else {
849-
throw .clusterSlotNodeTokenIsNotAnArray
825+
throw RESPDecodeError.tokenMismatch(expected: [.array], token: respToken)
850826
}
851827

852828
// IP, Port and Node Id are expected, additional metadata is optional
853829
guard array.count >= 3 else {
854-
throw .missingRequiredValueForSlotNode
830+
throw RESPDecodeError.invalidArraySize(array, minExpectedSize: 3)
855831
}
856832

857833
var iterator = array.makeIterator()
@@ -860,22 +836,22 @@ extension ValkeyClusterSlotRange.Node {
860836
guard let ipToken = iterator.next(),
861837
let ip = try? String(fromRESP: ipToken)
862838
else {
863-
throw .missingRequiredValueForSlotNode
839+
throw RESPDecodeError.missingToken(key: "ip", token: respToken)
864840
}
865841

866842
// Second element: port
867843
guard let portToken = iterator.next(),
868844
case .number(let portNumber) = portToken.value
869845
else {
870-
throw .missingRequiredValueForSlotNode
846+
throw RESPDecodeError.missingToken(key: "port", token: respToken)
871847
}
872848
let port = Int(portNumber)
873849

874850
// Third element: node ID
875851
guard let nodeIdToken = iterator.next(),
876852
let nodeId = try? String(fromRESP: nodeIdToken)
877853
else {
878-
throw .missingRequiredValueForSlotNode
854+
throw RESPDecodeError.missingToken(key: "node id", token: respToken)
879855
}
880856

881857
var metadata: [String: String] = [:]
@@ -904,7 +880,7 @@ extension ValkeyClusterSlotRange.Node {
904880
}
905881
}
906882
default:
907-
throw .clusterSlotNodeMetadataIsNotAnArrayOrMap
883+
throw RESPDecodeError.tokenMismatch(expected: [.array, .map], token: respToken)
908884
}
909885
}
910886

Sources/Valkey/RESP/RESPDecodeError.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,20 @@ public struct RESPDecodeError: Error {
6565
}
6666
}
6767
/// Does not match the expected array size
68-
public static func invalidArraySize(_ array: RESPToken.Array, expectedSize: Int) -> Self {
69-
.init(
68+
public static func invalidArraySize(_ array: RESPToken.Array, expectedSize: Int = -1, minExpectedSize: Int = -1) -> Self {
69+
let message: String
70+
if minExpectedSize > 0 {
71+
message = "Expected array of size at least \(minExpectedSize) but got an array of size \(array.count)"
72+
} else if expectedSize > 0 {
73+
message = "Expected array of size \(expectedSize) but got an array of size \(array.count)"
74+
} else {
75+
message = "Expected array of a different size but got an array of size \(array.count)"
76+
}
77+
78+
return .init(
7079
.invalidArraySize,
7180
token: .array(array),
72-
message: "Expected array of size \(expectedSize) but got an array of size \(array.count)"
81+
message: message
7382
)
7483
}
7584
/// Token associated with key is missing

0 commit comments

Comments
 (0)