{"record":{"id":"a47838c6c4137746","repo":"geektutu/7days-golang","slug":"nil-getter-a47838","errorCode":null,"errorMessage":"nil Getter","messagePattern":"nil Getter","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-cache/day4-consistent-hash/geecache/geecache.go","lineNumber":37,"sourceCode":"}\n\n// A GetterFunc implements Getter with a function.\ntype GetterFunc func(key string) ([]byte, error)\n\n// Get implements Getter interface function\nfunc (f GetterFunc) Get(key string) ([]byte, error) {\n\treturn f(key)\n}\n\nvar (\n\tmu     sync.RWMutex\n\tgroups = make(map[string]*Group)\n)\n\n// NewGroup create a new instance of Group\nfunc NewGroup(name string, cacheBytes int64, getter Getter) *Group {\n\tif getter == nil {\n\t\tpanic(\"nil Getter\")\n\t}\n\tmu.Lock()\n\tdefer mu.Unlock()\n\tg := &Group{\n\t\tname:      name,\n\t\tgetter:    getter,\n\t\tmainCache: cache{cacheBytes: cacheBytes},\n\t}\n\tgroups[name] = g\n\treturn g\n}\n\n// GetGroup returns the named group previously created with NewGroup, or\n// nil if there's no such group.\nfunc GetGroup(name string) *Group {\n\tmu.RLock()\n\tg := groups[name]\n\tmu.RUnlock()","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-cache/day4-consistent-hash/geecache/geecache.go#L19-L55","documentation":"Identical to error 90 but in the day4-consistent-hash version: NewGroup panics with \"nil Getter\" because the Group was constructed without a cache-miss loader. The library requires a non-nil Getter at construction and fails fast rather than nil-panicking later on a cache miss.","triggerScenarios":"geecache.NewGroup(name, cacheBytes, nil) — a nil Getter interface passed directly, or a typed-nil returned from a Getter factory.","commonSituations":"Getter produced by another subsystem that failed to initialize; variable declared but never assigned; mistaken use of a nil function value instead of a GetterFunc wrapper.","solutions":["Pass a valid Getter (e.g. geecache.GetterFunc closure) to NewGroup","Fix the upstream constructor that returns a typed-nil Getter","Add a unit test asserting NewGroup is never called with nil in your wiring code"],"exampleFix":"// before\ngeecache.NewGroup(\"users\", 1<<20, nil) // panic: nil Getter\n// after\ngeecache.NewGroup(\"users\", 1<<20, geecache.GetterFunc(func(key string) ([]byte, error) {\n    return fetchUser(key)\n}))","handlingStrategy":"validation","validationCode":"if getter == nil {\n    panic(\"NewGroup requires a non-nil Getter\")\n}\ng := geecache.NewGroup(\"users\", 1<<20, getter)","typeGuard":"func validGetter(g geecache.Getter) bool {\n    return g != nil\n}","tryCatchPattern":"// Fail fast at startup rather than catching:\nif r := recover(); r != nil { log.Fatalf(\"group init failed: %v\", r) }","preventionTips":["Use geecache.GetterFunc for plain functions so they can never be typed-nil","Enforce initialization order: DB/client first, groups second","Assert getters in unit tests for every group your app creates"],"tags":["go","cache","panic","nil-pointer"],"backgroundTag":"nil-cache-getter","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}