{"record":{"id":"66cfdb164c68d6db","repo":"flipped-aurora/gin-vue-admin","slug":"read-file-failed-w","errorCode":null,"errorMessage":"read file failed: %w","messagePattern":"read file failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/ast/extract_func.go","lineNumber":17,"sourceCode":"package ast\n\nimport (\n    \"fmt\"\n    \"go/ast\"\n    \"go/parser\"\n    \"go/token\"\n    \"os\"\n)\n\n// ExtractFuncSourceByPosition 根据文件路径与行号，提取包含该行的整个方法源码\n// 返回：方法名、完整源码、起止行号\nfunc ExtractFuncSourceByPosition(filePath string, line int) (name string, source string, startLine int, endLine int, err error) {\n    // 读取源文件\n    src, readErr := os.ReadFile(filePath)\n    if readErr != nil {\n        err = fmt.Errorf(\"read file failed: %w\", readErr)\n        return\n    }\n\n    // 解析 AST\n    fset := token.NewFileSet()\n    file, parseErr := parser.ParseFile(fset, filePath, src, parser.ParseComments)\n    if parseErr != nil {\n        err = fmt.Errorf(\"parse file failed: %w\", parseErr)\n        return\n    }\n\n    // 在 AST 中定位包含指定行号的函数声明\n    var target *ast.FuncDecl\n    ast.Inspect(file, func(n ast.Node) bool {\n        fd, ok := n.(*ast.FuncDecl)\n        if !ok {\n            return true\n        }","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/utils/ast/extract_func.go#L1-L35","documentation":"ExtractFuncSourceByPosition reads the file at filePath with os.ReadFile before AST parsing; any read failure (file missing, permission denied, path is a directory) is wrapped as 'read file failed: %w'. It's a filesystem-level failure, independent of Go syntax validity.","triggerScenarios":"Passing a relative path from a different working directory; file deleted/moved after the error was captured; typo'd path; reading a path you lack permission for.","commonSituations":"Tooling resolving paths from a stale index while files were refactored; running the extractor from a different cwd than the error's file root; container/host path mismatch.","solutions":["Pass an absolute path (filepath.Abs / root-relative to repo) and verify with os.Stat before calling","Confirm the file still exists at that location; regenerate/relocate if it was moved","Check file permissions if the path exists but read is denied"],"exampleFix":"// before\nname, src, _, _, err := ExtractFuncSourceByPosition(\"sys_user.go\", 55)\n// after\nabs, _ := filepath.Abs(\"server/service/system/sys_user.go\")\nname, src, _, _, err := ExtractFuncSourceByPosition(abs, 55)","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(filePath); err != nil {\n    return fmt.Errorf(\"file not readable before extraction: %w\", err)\n}","typeGuard":"func isReadableFile(path string) bool {\n    info, err := os.Stat(path)\n    return err == nil && !info.IsDir()\n}","tryCatchPattern":"name, source, start, end, err := ast.ExtractFuncSourceByPosition(path, line)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"read file failed\") {\n        log.Warnf(\"cannot read %s: %v — check path/cwd\", path, err)\n    }\n}","preventionTips":["Pass absolute paths derived from the repo root, not cwd-relative ones","Re-resolve file paths from a fresh index after refactors move files","Check os.Stat + non-directory before extraction","Surface the wrapped underlying error for exact cause (ENOENT vs EACCES)"],"tags":["filesystem","go","ast"],"backgroundTag":"file-not-found","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}