gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
76.72k stars 7.91k forks source link

ctx.GetString(key) should show some err info when cannot convert to a resonable value rather than return a wrong value with no more err info #3660

Open cruvie opened 12 months ago

cruvie commented 12 months ago

Description

ctx.GetString(key) should show some err info when cannot convert to a resonable value rather than return a wrong value with no more err info

How to reproduce

package main

import (
    "github.com/gin-gonic/gin"
    "log"
)

func main() {
    r := gin.Default()

    r.GET("/GetTest", func(c *gin.Context) {
        key := "myKet"
        c.Set(key, 5)
        get, exists := c.Get(key)
        if exists {
            log.Println("get==", get)
        }
        value := c.GetString(key)
        log.Println("value==", value)

        c.JSON(200, "ok")
    })

    err := r.Run(":7657")
    if err != nil {
        log.Println("初始化api失败==", err)
        return
    }
    //[GIN-debug] Listening and serving HTTP on :7657
    //2023/07/09 22:12:03 get== 5
    //2023/07/09 22:12:03 value==
    //[GIN] 2023/07/09 - 22:12:03 | 200 |     338.458µs |             ::1 | GET      "/GetTest"

}

Expectations

$ curl http://localhost:7657/GetTest
output
2023/07/09 22:12:03 value==5 

Actual result

$ curl http://localhost:7657/GetTest
2023/07/09 22:12:03 value==

Environment

kaylee595 commented 10 months ago

I think you should use Get instead of GetString directly when you are not sure about the type. To solve your problem you can do the following:

func setupRouter() *gin.Engine {
    r := gin.Default()
    r.GET("/GetTest", func(c *gin.Context) {
        key := "myKet"
        c.Set(key, 5)
        //get, exists := c.Get(key)
        //if exists {
        //  log.Println("get==", get)
        //}
        //value := c.GetString(key)
        //log.Println("value==", value)
        get, err := assertion[string](c.Get(key))
        if err != nil {
            log.Println(err)
            return
        }
        log.Println("get==", get)
        c.JSON(200, "ok")
    })
    return r
}

func assertion[T any](v any, exist bool) (T, error) {
    if exist {
        if got, ok := v.(T); ok {
            return got, nil
        } else {
            return got, fmt.Errorf("can not convert type: %T to %T ", v, *new(T))
        }
    }
    return *new(T), errors.New("not exist")
}

out

=== RUN   TestHttp
2023/08/16 00:42:56 can not convert type: int to string 
cruvie commented 10 months ago

@kaylee595 thank you, that's a good idea, but as I said in the title gin should give me some warning or error info rather a empty value