VS Code调试Go API时断点无法命中的问题求助
Go API项目断点无法命中排查
问题情况
调试简单Go程序时可正常命中断点,但在Go API项目中,API能正常响应Postman的POST请求(http://localhost:8080/api/dish/13),但设置在psqlrepo包insertOptionAvailable函数的断点始终无法触发。
项目核心代码
主函数代码
package main import ( "log" "os" // 省略其他导入 ) var ( menuRepo psqlrepo.MenuRepository = psqlrepo.NewMenuRepository() menuService service.MenuService = service.NewMenuService(menuRepo) menuController controller.MenuController = controller.NewMenuController(menuService) dishRepo psqlrepo.DishRepo = psqlrepo.NewDishRepo() dishService service.DishService = service.NewDishService(dishRepo) dishController controller.DishController = controller.NewDishController(dishService) httpRouter router.Router = router.NewMuxRouter() ) func main() { if err := godotenv.Load(); err != nil { log.Fatal(err) } httpRouter.POST("/api/menu/{id}", menuController.Create, middleware.ValidateToken) httpRouter.POST("/api/dish/{menu_id}", dishController.CreateDish, middleware.ValidateToken) httpRouter.SERVE(os.Getenv("PORT")) }
仓库层代码(断点设置位置)
断点设置在insertOptionAvailable函数的第一个if语句处:
package psqlrepo func insertOptionAvailable(optionAvailable entity.OptionsAvailables, optionID int, _db *sqlx.DB) error { var ( itExist bool ) if err := _db.QueryRow("select exists (select 1 from optionsAvailabe where name = $1)", optionAvailable.Name).Scan(&itExist); err != nil { return err } if itExist { return errors.New("this item already exists") } optionAvailable.CreatedAt = time.Now() optionAvailable.UpdatedAt = time.Now() _, err := _db.Exec("insert into optionsAvailabe(name, quantity, extra_price, option_id, updated_at, created_at) values($1, $2, $3, $4, $5, $6)", optionAvailable.Name, optionAvailable.Quantity, optionAvailable.ExtraPrice, optionID, optionAvailable.UpdatedAt, optionAvailable.CreatedAt) if err != nil { return err } return nil } func (*dishRepo) NewDish(dish entity.Dish, menuId int) (sql.Result, error) { var ( _db = db.NewPostgreSQLConection() itExist bool dishID int extraItems []entity.ExtraItem ) defer _db.Close() if err := _db.QueryRow("select exists (select 1 from dishes where name=$1)", &dish.Name).Scan(&itExist); err != nil { return nil, err } if itExist { return nil, errors.New("dish already exists") } dish.CreatedAt = time.Now() dish.UpdatedAt = time.Now() err := _db.QueryRow("insert into dishes(name, description, tags, menu_id, price, created_at, updated_at) values($1, $2, $3, $4, $5, $6, $7) returning id", dish.Name, dish.Description, dish.Tags, menuId, dish.Price, dish.CreatedAt, dish.UpdatedAt).Scan(&dishID) if err != nil { return nil, err } if len(*dish.Ingredients) > 0 { for _, ingredient := range *dish.Ingredients { if err := insertIngredient(ingredient, dishID, _db); err != nil { return nil, err } } } if len(*dish.Extras) > 0 { for _, option := range *dish.Extras { optionID, err := insertOption(option, dishID, _db) if err != nil || optionID == -1 { return nil, err } extraItems = append(extraItems, option.ExtraItems...) if len(extraItems) > 0 { for _, _optionAvailable := range extraItems { if err = insertOptionAvailable(_optionAvailable, optionID, _db); err != nil { return nil, err } } } } } return nil, nil }
服务层代码
package service import ( "database/sql" // 省略其他导入 ) type DishService interface { NewDish(dish entity.Dish, menuId int) (sql.Result, error) } var ( _dishRepo psqlrepo.DishRepo ) type dishService struct{} func NewDishService(dishRepo psqlrepo.DishRepo) DishService { _dishRepo = dishRepo return &dishService{} } func (*dishService) NewDish(dish entity.Dish, menuId int) (sql.Result, error) { return _dishRepo.NewDish(dish, menuId) }
控制器层代码
package controller import ( "encoding/json" "net/http" "strconv" // 省略其他导入 ) type DishController interface { CreateDish(rw http.ResponseWriter, r *http.Request) } type dishController struct{} var ( _dishService service.DishService ) func NewDishController(dishService service.DishService) DishController { _dishService = dishService return &dishController{} } func (*dishController) CreateDish(rw http.ResponseWriter, r *http.Request) { r.Header.Set("Content Type", "json/application") var ( dish entity.Dish response entity.Reponse vars = mux.Vars(r) ) menuID := vars["menu_id"] if menuID == "" { http.Error(rw, "menu id required", http.StatusBadRequest) return } id, err := strconv.Atoi(menuID) if err != nil { http.Error(rw, "error with menu id", http.StatusBadRequest) return } if err := json.NewDecoder(r.Body).Decode(&dish); err != nil { http.Error(rw, "Error getting body", http.StatusBadRequest) return } result, err := _dishService.NewDish(dish, id) if err != nil { http.Error(rw, err.Error(), http.StatusBadRequest) return } response = entity.Reponse{ Message: "Dish created successfully", Error: "", Data: result, } rw.WriteHeader(http.StatusOK) json.NewEncoder(rw).Encode(&response) }
当前launch.json配置
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. "version": "0.2.0", "configurations": [ { "name": "Launch Package", "type": "go", "request": "launch", "mode": "auto", "program": "${workspaceFolder}" }, { "name": "Launch file", "type": "go", "request": "launch", "mode": "debug", "program": "${file}" }, { "name": "Attach to Process", "type": "go", "request": "attach", "mode": "local", "processId": 0 }, ] }
环境信息
- 设备:M2 MacBook Air
- 已安装适配Apple Silicon的Go和VS Code版本
排查步骤
调整调试编译模式
修改launch.json中"Launch Package"配置的mode为debug,避免auto模式自动选择release编译(无调试信息):{ "name": "Launch Package", "type": "go", "request": "launch", "mode": "debug", "program": "${workspaceFolder}" }执行
go clean -cache清理编译缓存,确保生成带调试信息的二进制文件。验证代码执行路径
- 检查Postman请求体是否包含
Extras字段,且Extras下的ExtraItems不为空——只有这部分逻辑会触发insertOptionAvailable函数。 - 在
NewDish函数开头、调用insertOptionAvailable的循环处添加临时断点,确认代码是否走到该分支。
- 检查Postman请求体是否包含
更新调试工具与插件
- 确保VS Code的Go插件为最新版本。
- 更新Delve调试工具:执行
go install github.com/go-delve/delve/cmd/dlv@latest,然后执行dlv version确认架构为arm64。
适配Apple Silicon环境
- 关闭VS Code的Rosetta模式:右键VS Code图标→显示简介→取消勾选"使用Rosetta打开"。
- 确认Go环境变量
GOARCH为arm64,执行go env GOARCH查看输出。
检查接口实现与变量初始化
- 确认
psqlrepo.NewDishRepo()返回的实例正确实现了DishRepo接口,避免调用到未预期的代码分支。 - 检查全局变量
_dishRepo、_dishService的初始化是否正确,确保实际调用的是预期的实现。
- 确认
内容的提问来源于stack exchange,提问作者RoG Inz
相关产品推荐
相关产品推荐

