You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go HTTP服务单次请求返回3个JSON响应的问题排查求助

问题成因
  • 核心问题是错误处理分支写完响应后没有终止函数执行,ResponseWriter本身不会自动中断 handler 运行,流程会持续向下执行所有代码:
  1. 第一个判断检测到UUID解析失败,调用sendErrorResponse写入第一份错误JSON,执行完后没有return,代码继续运行到数据库查询逻辑
  2. 因UUID解析失败,uid变量是默认零值UUID,数据库查询不到对应记录,触发第二个错误判断,写入第二份错误JSON,执行完依然没有return,继续向下运行
  3. 最后一行代码将零值的job结构体序列化写入响应,最终生成3份拼接的JSON响应。
修复方案

在每个错误处理分支调用sendErrorResponse后新增return语句,终止后续逻辑执行即可:

func getJob(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    vars := mux.Vars(r)
    job_id := vars["job_id"]
    var job job
    
    // basic validation for UUID job_id
    uid, err := uuid.FromString(job_id)

    fmt.Println(uid)
    fmt.Println(err)

    if _, err := uuid.FromString(job_id); err != nil {
        sendErrorResponse(w, "Invalid job id "+job_id, err)
        return // 新增return终止流程
    }

    if result := db.Where("job_id = ?", uid).First(&job); result.Error != nil {
        sendErrorResponse(w, "Error retrieving job with "+job_id, result.Error)
        return // 新增return终止流程
    }

    json.NewEncoder(w).Encode(job)
}

可选优化

你可以复用前面已经解析得到的uid和err,不需要在if判断里重复解析UUID,减少不必要的计算:

uid, err := uuid.FromString(job_id)
if err != nil {
    sendErrorResponse(w, "Invalid job id "+job_id, err)
    return
}
相关资料查阅方向

你可以查看Go标准库net/http包的官方文档中关于Handler接口的定义说明,HTTP Handler的执行流程完全由开发者控制,写入响应后不会自动退出函数。

内容的提问来源于stack exchange,提问作者ricizawu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 02:42:01