Search code examples
gogoroutine

Request is not closed, after the function hit error


func login(c *gin.Context) {
    var req LoginRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{
            "error": "Invalid request",
        })
        return
    }
    fmt.Println("Request binding successful")

    if errs := handlers.VHandler.Validate(req); len(errs) > 0 && errs[0].Error {
        fmt.Println("Validation errors:", errs)
        c.JSON(http.StatusBadRequest, gin.H{
            "error": errs,
            "by":    "validator",
        })
        return
    }
    fmt.Println("Request validation successful")

    // Properly handle the database channel
    db := <-handlers.DB
    fmt.Println("DB connection acquired")
    defer func() {
        handlers.DB <- db
        fmt.Println("DB connection returned")
    }()

    // Fetch user from DB
    user, err := db.GetUserByUsername(req.Username)
    if err != nil {
        fmt.Println("DB error fetching user:", err)
        c.JSON(err.Code, gin.H{
            "error": err.Message,
        })
        return
    }
    fmt.Println("User fetched from DB:", user)

    // Compare password
    if !lib.CompareHashAndString(user.Password, req.Password) {
        fmt.Println("Password mismatch")
        c.JSON(http.StatusUnauthorized, gin.H{
            "error": "Invalid password",
        })
        return
    }
    fmt.Println("Password matched")

    // Generate JWT
    jwt, err := lib.SignJWT(user.ID)
    if err != nil {
        fmt.Println("JWT generation error:", err)
        c.JSON(err.Code, gin.H{
            "error": err.Message,
        })
        return
    }
    fmt.Println("JWT generated")

    // Successfully return login info
    c.JSON(http.StatusOK, gin.H{
        "message": "Login success",
        "tokens":  jwt,
        "user":    user,
    })
    fmt.Println("Response sent")
}

I have a login request handler, that is using a database connection, which is put in a goroutine.

I don't know, if this is a bad idea to put the database connection in a goroutine, if it seem like the error, is there any way I can handle it?

When the error hit by fetch user from db function, it stop and and return the db connection, but the request is not being closed.

I still got the DB connection returned message in the log.


Solution

  • Basicly, I put the database handler in a go-routine, because I thought, that multi-threading the database connection is a good idea.

    My database connection design pattern sucks, so I had to rewrite the database wrapper, and now it works like a champ!