Skip to content

Commit 70b0714

Browse files
authored
Throw error on failed persist value conversion (#614)
* Throw error on failed persist value conversion Add PersistError.invalidType, if you cannot cast to requested type then throw error * invalidType -> invalidConversion
1 parent 209e01d commit 70b0714

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

Sources/Hummingbird/Storage/MemoryPersistDriver.swift

+5-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ public actor MemoryPersistDriver<C: Clock>: PersistDriver where C.Duration == Du
3535

3636
public func get<Object: Codable & Sendable>(key: String, as: Object.Type) async throws -> Object? {
3737
guard let item = self.values[key] else { return nil }
38-
guard let expires = item.expires else { return item.value as? Object }
39-
guard self.clock.now <= expires else { return nil }
40-
return item.value as? Object
38+
if let expires = item.expires {
39+
guard self.clock.now <= expires else { return nil }
40+
}
41+
guard let object = item.value as? Object else { throw PersistError.invalidConversion }
42+
return object
4143
}
4244

4345
public func remove(key: String) async throws {

Sources/Hummingbird/Storage/PersistError.swift

+4
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616
public struct PersistError: Error, Equatable {
1717
private enum Internal {
1818
case duplicate
19+
case invalidConversion
1920
}
2021

2122
private let value: Internal
2223
private init(value: Internal) {
2324
self.value = value
2425
}
2526

27+
/// Failed to creating a persist entry as it already exists
2628
public static var duplicate: Self { .init(value: .duplicate) }
29+
/// Failed to convert a persist value to the requested type
30+
public static var invalidConversion: Self { .init(value: .invalidConversion) }
2731
}

Tests/HummingbirdTests/PersistTests.swift

+25-4
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,6 @@ final class PersistTests: XCTestCase {
140140
}
141141

142142
func testCodable() async throws {
143-
#if os(macOS)
144-
// disable macOS tests in CI. GH Actions are currently running this when they shouldn't
145-
guard Environment().get("CI") != "true" else { throw XCTSkip() }
146-
#endif
147143
struct TestCodable: Codable {
148144
let buffer: String
149145
}
@@ -171,6 +167,31 @@ final class PersistTests: XCTestCase {
171167
}
172168
}
173169

170+
func testInvalidGetAs() async throws {
171+
struct TestCodable: Codable {
172+
let buffer: String
173+
}
174+
let (router, persist) = try createRouter()
175+
router.put("/invalid") { _, _ -> HTTPResponse.Status in
176+
try await persist.set(key: "test", value: TestCodable(buffer: "hello"))
177+
return .ok
178+
}
179+
router.get("/invalid") { _, _ -> String? in
180+
do {
181+
return try await persist.get(key: "test", as: String.self)
182+
} catch let error as PersistError where error == .invalidConversion {
183+
throw HTTPError(.badRequest)
184+
}
185+
}
186+
let app = Application(router: router)
187+
try await app.test(.router) { client in
188+
try await client.execute(uri: "/invalid", method: .put)
189+
try await client.execute(uri: "/invalid", method: .get) { response in
190+
XCTAssertEqual(response.status, .badRequest)
191+
}
192+
}
193+
}
194+
174195
func testRemove() async throws {
175196
let (router, _) = try createRouter()
176197
let app = Application(responder: router.buildResponder())

0 commit comments

Comments
 (0)