Golang中如何从req.Response.StatusCode读取StatusCode

Golang中如何从req.Response.StatusCode读取StatusCode 我遇到了一个错误:

无效的内存地址或空指针解引用

我的代码如下所示:

func (ctr *Controller) Login(c *common.CPContext, req *http.Request, res http.ResponseWriter) (int, interface{}) {

	defer func() {
		var code = req.Response.StatusCode;  // 错误在这里!!

		log.Error(code)
		if code < 400 {
			user.LoginAttempts = 0
		} else {
			user.LoginAttempts = user.LoginAttempts + 1
		}
		_, err := user.Update(ctx, db, boil.Infer())
		if err != nil {
			log.Warningf("could not save/update user model: %v", err)
		}

	}()
   // ...
}

在这里我应该如何处理指针的情况?我只是想获取 http.Response,特别是这里的 http.Response.StatusCode


更多关于Golang中如何从req.Response.StatusCode读取StatusCode的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

嗨,这个可能也有帮助:https://github.com/Erilbeth/gocheck

更多关于Golang中如何从req.Response.StatusCode读取StatusCode的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我的猜测是,当你进入延迟函数时,req 已经被清理了。尝试将 req 传递给函数,看看是否能解决你的问题 😊

当你的延迟函数被调用时,所有东西都“消失”了。

看看 https://github.com/thoas/stats/blob/master/stats.go,它实现了你想要的功能。他们在记录器内部使用了 http.Hijacker

在Go语言中,http.RequestResponse字段仅在客户端请求中且收到服务器响应后才有效。在服务器端处理程序(如你的Login函数)中,req.Response通常为nil,因此直接访问req.Response.StatusCode会导致空指针解引用错误。

正确的做法是使用http.ResponseWriter来设置状态码,并在需要时记录它。以下是修改后的代码示例:

func (ctr *Controller) Login(c *common.CPContext, req *http.Request, res http.ResponseWriter) (int, interface{}) {
    var statusCode int // 用于存储状态码

    defer func() {
        log.Error(statusCode)
        if statusCode < 400 {
            user.LoginAttempts = 0
        } else {
            user.LoginAttempts = user.LoginAttempts + 1
        }
        _, err := user.Update(ctx, db, boil.Infer())
        if err != nil {
            log.Warningf("could not save/update user model: %v", err)
        }
    }()

    // 处理登录逻辑,并设置状态码
    // 例如:
    if loginSuccess {
        statusCode = 200
        res.WriteHeader(statusCode)
        return statusCode, someData
    } else {
        statusCode = 401
        res.WriteHeader(statusCode)
        return statusCode, errorData
    }
}

如果你需要在整个函数中跟踪状态码,可以将其作为变量传递,并在调用res.WriteHeader()时赋值。注意,WriteHeader只能调用一次,后续写入会使用已设置的状态码。

回到顶部