{"record":{"id":"10b082395a98865f","repo":"flipped-aurora/gin-vue-admin","slug":"db-no-init","errorCode":null,"errorMessage":"db no init","messagePattern":"db no init","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"server/global/global.go","lineNumber":57,"sourceCode":"\tGVA_MCP_SERVER          *server.MCPServer\n\tGVA_CACHE               gva_cache.Cache\n\tlock                    sync.RWMutex\n)\n\n// GetGlobalDBByDBName 通过名称获取db list中的db\nfunc GetGlobalDBByDBName(dbname string) *gorm.DB {\n\tlock.RLock()\n\tdefer lock.RUnlock()\n\treturn GVA_DBList[dbname]\n}\n\n// MustGetGlobalDBByDBName 通过名称获取db 如果不存在则panic\nfunc MustGetGlobalDBByDBName(dbname string) *gorm.DB {\n\tlock.RLock()\n\tdefer lock.RUnlock()\n\tdb, ok := GVA_DBList[dbname]\n\tif !ok || db == nil {\n\t\tpanic(\"db no init\")\n\t}\n\treturn db\n}\n\nfunc GetRedis(name string) redis.UniversalClient {\n\tredis, ok := GVA_REDISList[name]\n\tif !ok || redis == nil {\n\t\tpanic(fmt.Sprintf(\"redis `%s` no init\", name))\n\t}\n\treturn redis\n}\n","sourceCodeStart":39,"sourceCodeEnd":69,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/global/global.go#L39-L69","documentation":"MustGetGlobalDBByDBName looks up a named *gorm.DB in the global GVA_DBList registry and panics with the literal 'db no init' when the name is absent or the stored handle is nil. The Must* prefix signals the caller contract: the DB must already be registered during initialization, so absence is a programming/configuration error worth crashing on.","triggerScenarios":"Calling MustGetGlobalDBByDBName(\"name\") before initialize.Gorm/DBList has populated GVA_DBList, using a db-name that is not present in config.system.db-list / the datasource map, or after a failed DB connection left the entry nil.","commonSituations":"Typo in the business db name vs config.yaml datasource entries; calling a service that uses a secondary DB before initialization in a test without testutil.NewMemoryDB setup; connection failure during bootstrap silently skipping registration.","solutions":["Add the db name to the config datasource / db-list and ensure initialize.Gorm runs at startup","Fix the dbname string passed to MustGetGlobalDBByDBName to match a registered key exactly","Check startup logs for an earlier gorm connection failure that prevented registration","In tests, initialize GVA_DBList with the needed entries (e.g. server/internal/testutil.NewMemoryDB) before calling code that fetches by name"],"exampleFix":"// before\ndb := global.MustGetGlobalDBByDBName(\"biz\") // not in config\n// after (config.yaml)\nsystem:\n  db-list: [\"pgsql\", \"biz\"]\n// or guard:\nif db := global.GetGlobalDBByDBName(\"biz\"); db != nil { ... }","handlingStrategy":"type-guard","validationCode":"func dbReady(name string) bool { return global.GetGlobalDBByDBName(name) != nil } // call before Must variant","typeGuard":"func safeDB(name string) *gorm.DB { lock.RLock(); defer lock.RUnlock(); if db, ok := global.GVA_DBList[name]; ok && db != nil { return db }; return nil }","tryCatchPattern":"// recover around initialization-dependent calls\nfunc getDBSafe(name string) (db *gorm.DB, err error) { defer func() { if r := recover(); r != nil { if s, ok := r.(string); ok && s == \"db no init\" { err = fmt.Errorf(\"database %q not initialized\", name); return }; panic(r) } }(); return global.MustGetGlobalDBByDBName(name), nil }","preventionTips":["Keep db-list/datasource config in sync with every db name used in code (grep MustGetGlobalDBByDBName usages)","Centralize db-name constants instead of inline strings","Check startup logs to confirm every datasource registered before services run","In tests, seed GVA_DBList via server/internal/testutil.NewMemoryDB"],"tags":["gorm","panic","initialization","multi-database"],"backgroundTag":"database-not-initialized","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}