From 13432f0c09ef665a9e26d561670ef3b147bca219 Mon Sep 17 00:00:00 2001 From: Nathan Harris Date: Sat, 6 Jul 2019 08:23:01 -0700 Subject: [PATCH] Rename `RedisNIOError` to `RedisClientError` Motivation: To make it a little more generic, and to avoid turnover during renames (such as the planned rebranding in issue #61), `RedisClientError` more accurately reflects the source of the errors, as well as the responsibility of causing the bug. Modifications: - Rename `RedisNIOError` to `RedisClientError` - Rename `RedisError` file to `RedisErrors` - Add documentation of `RedisClientError` - Remove no longer used `.unsupportedOperation(method:message:)` value - Rename `.responseConversion(to:)` to `.failedRESPConversion(to:)` Result: Names of `RedisClientError` should be more descriptive, less prone to turnover, and more documented for users to understand the issues related to these thrown errors. --- Sources/RedisNIO/Commands/BasicCommands.swift | 2 +- Sources/RedisNIO/Commands/ListCommands.swift | 4 ++-- .../RedisNIO/Commands/SortedSetCommands.swift | 6 +++--- Sources/RedisNIO/Extensions/SwiftNIO.swift | 2 +- Sources/RedisNIO/RedisConnection.swift | 2 +- .../{RedisError.swift => RedisErrors.swift} | 19 ++++++++++--------- .../RedisNIOTests/RedisConnectionTests.swift | 2 +- 7 files changed, 19 insertions(+), 18 deletions(-) rename Sources/RedisNIO/{RedisError.swift => RedisErrors.swift} (55%) diff --git a/Sources/RedisNIO/Commands/BasicCommands.swift b/Sources/RedisNIO/Commands/BasicCommands.swift index 3584fff..c1a71ba 100644 --- a/Sources/RedisNIO/Commands/BasicCommands.swift +++ b/Sources/RedisNIO/Commands/BasicCommands.swift @@ -160,7 +160,7 @@ extension RedisClient { let value = result[0].string, let position = Int(value) else { - throw RedisNIOError.assertionFailure(message: "Unexpected value in response: \(result[0])") + throw RedisClientError.assertionFailure(message: "Unexpected value in response: \(result[0])") } return position } diff --git a/Sources/RedisNIO/Commands/ListCommands.swift b/Sources/RedisNIO/Commands/ListCommands.swift index 8115ddf..6ca0746 100644 --- a/Sources/RedisNIO/Commands/ListCommands.swift +++ b/Sources/RedisNIO/Commands/ListCommands.swift @@ -442,11 +442,11 @@ extension RedisClient { .flatMapThrowing { guard !$0.isNull else { return nil } guard let response = [RESPValue](fromRESP: $0) else { - throw RedisNIOError.responseConversion(to: [RESPValue].self) + throw RedisClientError.failedRESPConversion(to: [RESPValue].self) } assert(response.count == 2, "Unexpected response size returned!") guard let key = response[0].string else { - throw RedisNIOError.assertionFailure(message: "Unexpected structure in response: \(response)") + throw RedisClientError.assertionFailure(message: "Unexpected structure in response: \(response)") } return (key, response[1]) } diff --git a/Sources/RedisNIO/Commands/SortedSetCommands.swift b/Sources/RedisNIO/Commands/SortedSetCommands.swift index dac5df6..c202ebf 100644 --- a/Sources/RedisNIO/Commands/SortedSetCommands.swift +++ b/Sources/RedisNIO/Commands/SortedSetCommands.swift @@ -31,7 +31,7 @@ extension RedisClient { let scoreItem = response[scoreIsFirst ? index : index + 1] guard let score = Double(fromRESP: scoreItem) else { - throw RedisNIOError.assertionFailure(message: "Unexpected response: '\(scoreItem)'") + throw RedisClientError.assertionFailure(message: "Unexpected response: '\(scoreItem)'") } let elementIndex = scoreIsFirst ? index + 1 : index @@ -456,14 +456,14 @@ extension RedisClient { .flatMapThrowing { guard !$0.isNull else { return nil } guard let response = [RESPValue](fromRESP: $0) else { - throw RedisNIOError.responseConversion(to: [RESPValue].self) + throw RedisClientError.failedRESPConversion(to: [RESPValue].self) } assert(response.count == 3, "Unexpected response size returned!") guard let key = response[0].string, let score = Double(fromRESP: response[1]) else { - throw RedisNIOError.assertionFailure(message: "Unexpected structure in response: \(response)") + throw RedisClientError.assertionFailure(message: "Unexpected structure in response: \(response)") } return (key, score, response[2]) } diff --git a/Sources/RedisNIO/Extensions/SwiftNIO.swift b/Sources/RedisNIO/Extensions/SwiftNIO.swift index 20e7880..057d8e0 100644 --- a/Sources/RedisNIO/Extensions/SwiftNIO.swift +++ b/Sources/RedisNIO/Extensions/SwiftNIO.swift @@ -30,7 +30,7 @@ extension EventLoopFuture where Value == RESPValue { { return self.flatMapThrowing { guard let value = T(fromRESP: $0) else { - throw RedisNIOError.responseConversion(to: type) + throw RedisClientError.failedRESPConversion(to: type) } return value } diff --git a/Sources/RedisNIO/RedisConnection.swift b/Sources/RedisNIO/RedisConnection.swift index 5fb16a0..374e1fd 100644 --- a/Sources/RedisNIO/RedisConnection.swift +++ b/Sources/RedisNIO/RedisConnection.swift @@ -183,7 +183,7 @@ extension RedisConnection { /// If a `RedisError` is returned, the future will be failed instead. public func send(command: String, with arguments: [RESPValue]) -> EventLoopFuture { guard self.isConnected else { - let error = RedisNIOError.connectionClosed + let error = RedisClientError.connectionClosed logger.warning("\(error.localizedDescription)") return self.channel.eventLoop.makeFailedFuture(error) } diff --git a/Sources/RedisNIO/RedisError.swift b/Sources/RedisNIO/RedisErrors.swift similarity index 55% rename from Sources/RedisNIO/RedisError.swift rename to Sources/RedisNIO/RedisErrors.swift index 1a6c4a2..bffbb90 100644 --- a/Sources/RedisNIO/RedisError.swift +++ b/Sources/RedisNIO/RedisErrors.swift @@ -14,28 +14,29 @@ import protocol Foundation.LocalizedError -/// When working with RedisNIO, several errors are thrown to indicate problems -/// with state, assertions, or otherwise. -public enum RedisNIOError: LocalizedError { +/// When working with `RedisClient`, runtime errors can be thrown to indicate problems with connection state, decoding assertions, or otherwise. +public enum RedisClientError: LocalizedError { + /// The connection is closed, but was used to try and send a command to Redis. case connectionClosed - case responseConversion(to: Any.Type) - case unsupportedOperation(method: StaticString, message: String) + /// Conversion from `RESPValue` to the specified type failed. + /// If this is ever triggered, please capture the original `RESPValue` value. + case failedRESPConversion(to: Any.Type) + /// Expectations of message structures were not met. + /// If this is ever triggered, please capture the original byte message from Redis along with the command and arguments to Redis. case assertionFailure(message: String) public var errorDescription: String? { let message: String switch self { case .connectionClosed: message = "Connection was closed while trying to send command." - case let .responseConversion(type): message = "Failed to convert RESP to \(type)" - case let .unsupportedOperation(method, helpText): message = "\(method) - \(helpText)" + case let .failedRESPConversion(type): message = "Failed to convert RESP to \(type)" case let .assertionFailure(text): message = text } return "RedisNIO: \(message)" } } -/// When sending commands to a Redis server, errors caught will be returned as an error message. -/// These messages are represented by `RedisError` instances. +/// If something goes wrong with a command within Redis, it will respond with an error that is captured and represented by instances of this type. public struct RedisError: LocalizedError { public let message: String diff --git a/Tests/RedisNIOTests/RedisConnectionTests.swift b/Tests/RedisNIOTests/RedisConnectionTests.swift index c10e794..6dd2268 100644 --- a/Tests/RedisNIOTests/RedisConnectionTests.swift +++ b/Tests/RedisNIOTests/RedisConnectionTests.swift @@ -42,7 +42,7 @@ final class RedisConnectionTests: RedisIntegrationTestCase { _ = try self.connection.ping().wait() XCTFail("ping() should throw when connection is closed.") } catch { - XCTAssertTrue(error is RedisNIOError) + XCTAssertTrue(error is RedisClientError) } }