From 92c8a3b955b2ff22e9d69334a37affa675fa152f Mon Sep 17 00:00:00 2001 From: Mahmoud-Emad Date: Sun, 14 Sep 2025 18:15:23 +0300 Subject: [PATCH] fix: improve Redis response parsing and error handling - Add error handling for non-array and error responses - Introduce `strget()` for safer string conversion from RValue - Update AGE client to use `strget()` for key retrieval - Change AGE verify methods to expect a string response - Handle multiple response types when listing AGE keys --- lib/core/redisclient/redisclient_send.v | 11 ++++++ lib/data/resp/resp_model.v | 12 +++++-- lib/hero/crypt/age.v | 45 ++++++++++++++++++------- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/lib/core/redisclient/redisclient_send.v b/lib/core/redisclient/redisclient_send.v index 3e63738c..77748642 100644 --- a/lib/core/redisclient/redisclient_send.v +++ b/lib/core/redisclient/redisclient_send.v @@ -83,5 +83,16 @@ pub fn (mut r Redis) send_expect_list(items []string) ![]resp.RValue { } r.write_cmds(items)! res := r.get_response()! + + // Check if we got an error response + if res is resp.RError { + return error('Redis error: ${res.value}') + } + + // Check if we got an array response + if res !is resp.RArray { + return error('Expected array response but got ${res.type_name()}. Response: ${resp.get_redis_value(res)}') + } + return resp.get_redis_array(res) } diff --git a/lib/data/resp/resp_model.v b/lib/data/resp/resp_model.v index 236e2355..8a5cf633 100644 --- a/lib/data/resp/resp_model.v +++ b/lib/data/resp/resp_model.v @@ -103,7 +103,7 @@ pub fn (v RValue) u32() u32 { pub fn (v RValue) strget() string { match v { RInt { - return v.str() + return v.value.str() } // RArray{ // return v.str() @@ -112,10 +112,16 @@ pub fn (v RValue) strget() string { return v.value.bytestr() } RString { - return v.str() + return v.value + } + RError { + return v.value + } + RNil { + return '' } else { - panic('could not find type') + panic('could not find type: ${v.type_name()}') } } } diff --git a/lib/hero/crypt/age.v b/lib/hero/crypt/age.v index 0245e220..c51e0849 100644 --- a/lib/hero/crypt/age.v +++ b/lib/hero/crypt/age.v @@ -1,6 +1,7 @@ module crypt import freeflowuniverse.herolib.core.redisclient +import freeflowuniverse.herolib.data.resp // Stateless AGE operations @@ -13,8 +14,8 @@ pub fn (mut client AGEClient) generate_keypair() !KeyPair { } return KeyPair{ - recipient: response[0].str() - identity: response[1].str() + recipient: response[0].strget() + identity: response[1].strget() } } @@ -27,8 +28,8 @@ pub fn (mut client AGEClient) generate_signing_keypair() !SigningKeyPair { } return SigningKeyPair{ - verify_key: response[0].str() - sign_key: response[1].str() + verify_key: response[0].strget() + sign_key: response[1].strget() } } @@ -57,8 +58,8 @@ pub fn (mut client AGEClient) sign(sign_key string, message string) !SignatureRe // verify verifies a signature with the verification key pub fn (mut client AGEClient) verify(verify_key string, message string, signature string) !bool { - result := client.redis.send_expect_int(['AGE', 'VERIFY', verify_key, message, signature])! - return result == 1 + result := client.redis.send_expect_str(['AGE', 'VERIFY', verify_key, message, signature])! + return result == '1' } // Key-managed AGE operations @@ -72,8 +73,8 @@ pub fn (mut client AGEClient) create_named_keypair(name string) !KeyPair { } return KeyPair{ - recipient: response[0].str() - identity: response[1].str() + recipient: response[0].strget() + identity: response[1].strget() } } @@ -86,8 +87,8 @@ pub fn (mut client AGEClient) create_named_signing_keypair(name string) !Signing } return SigningKeyPair{ - verify_key: response[0].str() - sign_key: response[1].str() + verify_key: response[0].strget() + sign_key: response[1].strget() } } @@ -116,8 +117,8 @@ pub fn (mut client AGEClient) sign_with_named_key(key_name string, message strin // verify_with_named_key verifies a signature using a named verification key pub fn (mut client AGEClient) verify_with_named_key(key_name string, message string, signature string) !bool { - result := client.redis.send_expect_int(['AGE', 'VERIFYNAME', key_name, message, signature])! - return result == 1 + result := client.redis.send_expect_str(['AGE', 'VERIFYNAME', key_name, message, signature])! + return result == '1' } // list_keys lists all stored AGE keys @@ -126,7 +127,25 @@ pub fn (mut client AGEClient) list_keys() ![]string { mut keys := []string{} for i in 0 .. response.len { - keys << response[i].str() + item := response[i] + // Handle different response types + match item { + resp.RString { + keys << item.value + } + resp.RBString { + keys << item.value.bytestr() + } + resp.RArray { + // If it's an array, try to get the first element as the key name + if item.values.len > 0 { + keys << item.values[0].strget() + } + } + else { + keys << item.strget() + } + } } return keys