简体   繁体   English

Redis 不会将 WRONGTYPE 作为事务中的错误返回

[英]Redis doesn't return WRONGTYPE as an error in a transaction

Appologies if this was already asked.抱歉,如果这已经被问到了。 First, let me show how to reproduce my problem:首先,让我展示如何重现我的问题:

  1. Run Redis in a docker container在 docker 容器中运行 Redis
  2. Connect to Redis and execute the following command:连接到 Redis 并执行以下命令:
> SET test 10
  1. In Go, run this code:在 Go 中,运行以下代码:
func main() {
    redisClient := getConnection() // Abstracting get connection for simplicity

    r, err := redisClient.Do("HSET", "test", "f1", "v1", "f2", "v2")
    fmt.Printf("%+v e: %+v\n")
}

Fair enough, in this step the following error is shown (this means err != nil ):很公平,在这一步中显示了以下错误(这意味着err != nil ):

WRONGTYPE Operation against a key holding the wrong kind of value e: WRONGTYPE Operation against a key holding the wrong kind of value
  1. In comparison, execute the following code:相比之下,执行以下代码:
func main() {
    redisClient := getConnection()

    redisClient.Send("MULTI")

    redisClient.Send("HSET", "test", "f1", "v1", "f2", "v2")

    r, err := redisClient.Do("EXEC")
    fmt.Printf("%+v e: %+v\n")
}

The line being printed is:正在打印的行是:

WRONGTYPE Operation against a key holding the wrong kind of value e: <nil>

This seems inconsistent to me as I would expect MULTI to return the WRONGTYPE in the error variable as well.这对我来说似乎不一致,因为我希望MULTI也会在错误变量中返回WRONGTYPE

Is this an intended behavior or am I missing something?这是预期的行为还是我错过了什么?

There are two results for each command in a Redis transaction. Redis 事务中的每个命令都有两个结果。 One is the result for adding the command to the transaction and the other is the result for executing the command in the transaction.一种是将命令添加到事务中的结果,另一种是在事务中执行命令的结果。

The Do method returns the result for adding the command to the transaction. Do方法返回将命令添加到事务的结果。

The Redis EXEC command returns an array where each element is the result of executing the command in the transaction. Redis EXEC命令返回一个数组,其中每个元素都是在事务中执行命令的结果。 Examine each element to check individual command errors:检查每个元素以检查单个命令错误:

values, err := redis.Values(redisClient.Do("EXEC"))
if err != nil {
    // Handle error
}
if err, ok := values[0].(redis.Error); ok {
    // Handle error for command 0.
    // Adjust the index to match the actual index of 
    // of the HMSET command in the transaction.
}

A helper function for testing transaction command errors may be useful:用于测试事务命令错误的助手 function 可能有用:

func execValues(reply interface{}, err error) ([]interface{}, error) {
    if err != nil {
        return nil, err
    }
    values, ok := reply.([]interface{})
    if !ok {
        return nil, fmt.Errorf("unexpected type for EXEC reply, got type %T", reply)
    }
    for _, v := range values {
        if err, ok := v.(redis.Error); ok {
            return values, err
        }
    }
    return values, nil
}

Use it like this:像这样使用它:

values, err := execValues(redisClient.Do("EXEC"))
if err != nil {
    // Handle error.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM