* Get a value from cache with automatic JSON deserialization * @param key - Cache key to retrieve * @returns Result containing parsed value, null if not found, or an error
(key: CacheKey)
| 52 | * @returns Result containing parsed value, null if not found, or an error |
| 53 | */ |
| 54 | async get<T>(key: CacheKey): Promise<Result<T | null, CacheError>> { |
| 55 | // Check Redis availability first |
| 56 | if (!this.isRedisClientReady()) { |
| 57 | return err({ |
| 58 | code: ErrorCode.RedisConnectionError, |
| 59 | }); |
| 60 | } |
| 61 | |
| 62 | const validation = validateInputs([key, ZCacheKey]); |
| 63 | if (!validation.ok) { |
| 64 | return validation; |
| 65 | } |
| 66 | |
| 67 | try { |
| 68 | const value = await this.withTimeout(this.redis.get(key)); |
| 69 | if (value === null) { |
| 70 | return ok(null); |
| 71 | } |
| 72 | |
| 73 | // Parse JSON - all data should be valid JSON since we stringify on set |
| 74 | try { |
| 75 | return ok(JSON.parse(value) as T); |
| 76 | } catch (parseError) { |
| 77 | // JSON parse failure indicates corrupted cache data - treat as cache miss |
| 78 | logger.warn( |
| 79 | { |
| 80 | key, |
| 81 | parseError, |
| 82 | }, |
| 83 | "Corrupted cache data detected, treating as cache miss" |
| 84 | ); |
| 85 | return err({ |
| 86 | code: ErrorCode.CacheCorruptionError, |
| 87 | }); |
| 88 | } |
| 89 | } catch (error) { |
| 90 | logger.error({ error, key }, "Cache get operation failed"); |
| 91 | return err({ |
| 92 | code: ErrorCode.RedisOperationError, |
| 93 | }); |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | /** |
| 98 | * Check if a key exists in cache. |