{"record":{"id":"d4a1e1b9c811da8e","repo":"flipped-aurora/gin-vue-admin","slug":"gorm-d4a1e1","errorCode":null,"errorMessage":"插件 gorm 注入目标不能为空","messagePattern":"插件 gorm 注入目标不能为空","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/ast/plugin_initialize_gorm.go","lineNumber":85,"sourceCode":"\t\t\t\t// 删除参数\n\t\t\t\tcallExpr.Args = append(callExpr.Args[:i], callExpr.Args[i+1:]...)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t})\n\n\tif needRollBackImport {\n\t\t_ = NewImport(a.ImportPath).Rollback(file)\n\t}\n\n\treturn nil\n}\n\nfunc (a *PluginInitializeGorm) Injection(file *ast.File) error {\n\tif file == nil {\n\t\treturn fmt.Errorf(\"插件 gorm 注入目标不能为空\")\n\t}\n\n\tvar targetCall *ast.CallExpr\n\tast.Inspect(file, func(n ast.Node) bool {\n\t\tcallExpr, ok := n.(*ast.CallExpr)\n\t\tif !ok {\n\t\t\treturn true\n\t\t}\n\n\t\tselExpr, ok := callExpr.Fun.(*ast.SelectorExpr)\n\t\tif !ok || selExpr.Sel.Name != \"AutoMigrate\" {\n\t\t\treturn true\n\t\t}\n\n\t\tif a.isTargetAutoMigrateCall(callExpr) {\n\t\t\ttargetCall = callExpr\n\t\t\treturn false\n\t\t}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/utils/ast/plugin_initialize_gorm.go#L67-L103","documentation":"PluginInitializeGorm.Injection injects AutoMigrate registration into a plugin's gorm initialization. The first guard rejects a nil *ast.File, meaning no parsed AST was supplied. Without a parsed file the injector has nothing to inspect or modify.","triggerScenarios":"Calling Injection(nil) directly, or propagating the nil *ast.File from a failed Parse(filename, writer) call without checking its error.","commonSituations":"Plugin codegen pipeline ignores Parse errors and continues; tests invoking Injection without a parsed plugin gorm.go; refactoring moved Parse/Injection calls and dropped error handling.","solutions":["Check the error from Parse and only call Injection with a non-nil *ast.File","Fix the underlying file-read/parse failure before retrying the injection","In tests, build the *ast.File via the package's Parse helper instead of passing nil"],"exampleFix":"// before\nfile, _ := p.Parse(\"\", writer)\n_ = p.Injection(file)\n// after\nfile, err := p.Parse(\"\", writer)\nif err != nil {\n    return err\n}\nreturn p.Injection(file)","handlingStrategy":"type-guard","validationCode":"file, err := plugin.Parse(\"\", writer)\nif err != nil {\n    return err\n}\nif file == nil {\n    return fmt.Errorf(\"parse returned nil file\")\n}","typeGuard":"func hasParsedFile(f *ast.File) bool { return f != nil }","tryCatchPattern":"if err := pluginInj.Injection(file); err != nil {\n    if strings.Contains(err.Error(), \"注入目标不能为空\") {\n        return fmt.Errorf(\"pipeline bug: nil AST reached plugin gorm injection: %w\", err)\n    }\n    return err\n}","preventionTips":["Check Parse errors before calling Injection","Keep Parse/Injection/Format calls together in one guarded pipeline step","Test the plugin codegen path with a malformed file to confirm errors propagate"],"tags":["go","ast","gorm","plugin","nil-check"],"backgroundTag":"nil-ast-target","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}