Skip to content

Commit

Permalink
Throw error on failed persist value conversion (#614)
Browse files Browse the repository at this point in the history
* Throw error on failed persist value conversion

Add PersistError.invalidType, if you cannot cast to requested type then throw error

* invalidType -> invalidConversion
  • Loading branch information
adam-fowler authored Nov 20, 2024
1 parent 209e01d commit 70b0714
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
8 changes: 5 additions & 3 deletions Sources/Hummingbird/Storage/MemoryPersistDriver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ public actor MemoryPersistDriver<C: Clock>: PersistDriver where C.Duration == Du

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

public func remove(key: String) async throws {
Expand Down
4 changes: 4 additions & 0 deletions Sources/Hummingbird/Storage/PersistError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@
public struct PersistError: Error, Equatable {
private enum Internal {
case duplicate
case invalidConversion
}

private let value: Internal
private init(value: Internal) {
self.value = value
}

/// Failed to creating a persist entry as it already exists
public static var duplicate: Self { .init(value: .duplicate) }
/// Failed to convert a persist value to the requested type
public static var invalidConversion: Self { .init(value: .invalidConversion) }
}
29 changes: 25 additions & 4 deletions Tests/HummingbirdTests/PersistTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,6 @@ final class PersistTests: XCTestCase {
}

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

func testInvalidGetAs() async throws {
struct TestCodable: Codable {
let buffer: String
}
let (router, persist) = try createRouter()
router.put("/invalid") { _, _ -> HTTPResponse.Status in
try await persist.set(key: "test", value: TestCodable(buffer: "hello"))
return .ok
}
router.get("/invalid") { _, _ -> String? in
do {
return try await persist.get(key: "test", as: String.self)
} catch let error as PersistError where error == .invalidConversion {
throw HTTPError(.badRequest)
}
}
let app = Application(router: router)
try await app.test(.router) { client in
try await client.execute(uri: "/invalid", method: .put)
try await client.execute(uri: "/invalid", method: .get) { response in
XCTAssertEqual(response.status, .badRequest)
}
}
}

func testRemove() async throws {
let (router, _) = try createRouter()
let app = Application(responder: router.buildResponder())
Expand Down

0 comments on commit 70b0714

Please sign in to comment.