{"record":{"id":"77bd64c54631f6a2","repo":"flipped-aurora/gin-vue-admin","slug":"error-77bd64","errorCode":null,"errorMessage":"自动代码数据库未初始化","messagePattern":"自动代码数据库未初始化","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"server/service/system/auto_code_persistence.go","lineNumber":24,"sourceCode":"\t\"errors\"\n\t\"fmt\"\n\n\tmodel \"github.com/flipped-aurora/gin-vue-admin/server/model/system\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/system/request\"\n\t\"gorm.io/gorm\"\n)\n\nvar errAutoCodeMenuConflict = errors.New(\"自动代码菜单名称冲突\")\n\nfunc persistAutoCodeMetadata(\n\tctx context.Context,\n\tdb *gorm.DB,\n\tinfo request.AutoCode,\n\tpackageTemplate string,\n\thistory request.SysAutoHistoryCreate,\n) error {\n\tif db == nil {\n\t\treturn errors.New(\"自动代码数据库未初始化\")\n\t}\n\treturn db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {\n\t\tif err := persistAutoCodeAPIs(tx, info, &history); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := persistAutoCodeMenu(tx, info, packageTemplate, &history); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := persistAutoCodeExportTemplate(tx, info, &history); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tentity := history.Create()\n\t\tif err := tx.Create(&entity).Error; err != nil {\n\t\t\treturn fmt.Errorf(\"创建自动代码历史失败: %w\", err)\n\t\t}\n\t\treturn nil\n\t})\n}","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_persistence.go#L6-L42","documentation":"persistAutoCodeMetadata requires a non-nil *gorm.DB handle; if db == nil it refuses to run and returns this error before opening a transaction. It protects the multi-row insert (APIs, menu, history) from nil-pointer panics when the caller has no initialized database connection.","triggerScenarios":"Calling persistAutoCodeMetadata (directly or via the service entry) with a nil db argument — typically when global.GVA_DB was never initialized or a caller passed nil explicitly.","commonSituations":"Unit/integration tests constructing the service without testutil.NewMemoryDB; misconfigured database so initialization silently skipped; calling persistence logic before server bootstrap completed.","solutions":["Initialize the DB before invoking persistence: ensure config.yaml database settings are correct so global.GVA_DB is set at startup.","In tests, use server/internal/testutil.NewMemoryDB(t, models...) to inject an in-memory GORM DB.","Add a startup assertion that global.GVA_DB != nil to fail fast on config errors."],"exampleFix":"// before\ndb := global.GVA_DB // nil when uninitialized\nerr := persistAutoCodeMetadata(ctx, db, info, template, history)\n// after\nif global.GVA_DB == nil {\n    return errors.New(\"数据库未初始化，请检查 config.yaml 数据库配置\")\n}\nerr := persistAutoCodeMetadata(ctx, global.GVA_DB, info, template, history)","handlingStrategy":"validation","validationCode":"if db == nil {\n    return errors.New(\"自动代码数据库未初始化\")\n}\n// or at caller:\nif global.GVA_DB == nil {\n    return errors.New(\"数据库连接未初始化，请检查启动配置\")\n}","typeGuard":"func dbReady(db *gorm.DB) bool {\n    return db != nil\n}","tryCatchPattern":"if err := persistAutoCodeMetadata(ctx, db, info, template, history); err != nil {\n    if err.Error() == \"自动代码数据库未初始化\" {\n        return fmt.Errorf(\"数据库未连接: %w\", err)\n    }\n    return err\n}","preventionTips":["Verify startup logs show successful DB connection before using auto-code.","In tests always construct the DB via server/internal/testutil.NewMemoryDB.","Fail fast at boot if global.GVA_DB is nil."],"tags":["nil-pointer","database","initialization"],"backgroundTag":"missing-db-initialization","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}