diff options
| author | Shulhan <ms@kilabit.info> | 2021-10-09 19:06:21 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2021-10-09 22:22:02 +0700 |
| commit | 7e255b79c1c1afaffb1b6f8790f7d77b382acb69 (patch) | |
| tree | cef6f0c1e02ef7d7192fe5bc9f9fa01ef217fef5 | |
| parent | aea6a7b344975770dc5ea03851856b825716b06b (diff) | |
| download | pakakeh.go-7e255b79c1c1afaffb1b6f8790f7d77b382acb69.tar.xz | |
lib/memfs: prefix all error when the method or function names
One of the hardest when multiple packages is used is to detect where
there error happened. For example, if a program return an error io.EOF,
it's hard to detect the exact method or function that caused its,
especially when processing multiple files with network connection.
| -rw-r--r-- | lib/memfs/embed.go | 2 | ||||
| -rw-r--r-- | lib/memfs/memfs.go | 75 | ||||
| -rw-r--r-- | lib/memfs/memfs_test.go | 14 | ||||
| -rw-r--r-- | lib/memfs/node.go | 45 | ||||
| -rw-r--r-- | lib/memfs/node_test.go | 9 |
5 files changed, 86 insertions, 59 deletions
diff --git a/lib/memfs/embed.go b/lib/memfs/embed.go index 7e234629..3f66f57b 100644 --- a/lib/memfs/embed.go +++ b/lib/memfs/embed.go @@ -42,7 +42,7 @@ type generateData struct { // file using gzip and set Node.ContentEncoding to "gzip". // func (mfs *MemFS) GoEmbed(pkgName, varName, out, contentEncoding string) (err error) { - logp := "MemFS.GoEmbed" + logp := "GoEmbed" if len(pkgName) == 0 { pkgName = DefaultEmbedPackageName diff --git a/lib/memfs/memfs.go b/lib/memfs/memfs.go index 936c0452..a6751ddf 100644 --- a/lib/memfs/memfs.go +++ b/lib/memfs/memfs.go @@ -94,6 +94,8 @@ func Merge(params ...*MemFS) (merged *MemFS) { // list of regular expresssion for Including or Excluding files. // func New(opts *Options) (mfs *MemFS, err error) { + logp := "New" + if opts == nil { opts = &Options{} } @@ -110,21 +112,21 @@ func New(opts *Options) (mfs *MemFS, err error) { for _, inc := range opts.Includes { re, err := regexp.Compile(inc) if err != nil { - return nil, fmt.Errorf("memfs.New: %w", err) + return nil, fmt.Errorf("%s: %w", logp, err) } mfs.incRE = append(mfs.incRE, re) } for _, exc := range opts.Excludes { re, err := regexp.Compile(exc) if err != nil { - return nil, fmt.Errorf("memfs.New: %w", err) + return nil, fmt.Errorf("%s: %w", logp, err) } mfs.excRE = append(mfs.excRE, re) } err = mfs.mount() if err != nil { - return nil, fmt.Errorf("memfs.New: %w", err) + return nil, fmt.Errorf("%s: %w", logp, err) } return mfs, nil @@ -157,13 +159,16 @@ func (mfs *MemFS) AddChild(parent *Node, fi os.FileInfo) (child *Node, err error // Any directories in the internal path will be generated automatically if its // not exist. // -func (mfs *MemFS) AddFile(internalPath, externalPath string) (*Node, error) { +func (mfs *MemFS) AddFile(internalPath, externalPath string) (node *Node, err error) { if len(internalPath) == 0 { return nil, nil } + + logp := "AddFile" + fi, err := os.Stat(externalPath) if err != nil { - return nil, fmt.Errorf("memfs.AddFile: %w", err) + return nil, fmt.Errorf("%s: %w", logp, err) } var parent *Node @@ -203,7 +208,7 @@ func (mfs *MemFS) AddFile(internalPath, externalPath string) (*Node, error) { } path = filepath.Join(path, base) - node := &Node{ + node = &Node{ SysPath: externalPath, Path: path, name: base, @@ -216,12 +221,12 @@ func (mfs *MemFS) AddFile(internalPath, externalPath string) (*Node, error) { err = node.updateContent(mfs.Opts.MaxFileSize) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %w", logp, err) } err = node.updateContentType() if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %w", logp, err) } parent.Childs = append(parent.Childs, node) @@ -241,6 +246,7 @@ func (mfs *MemFS) AddFile(internalPath, externalPath string) (*Node, error) { // func (mfs *MemFS) ContentEncode(encoding string) (err error) { var ( + logp = "ContentEncode" buf bytes.Buffer encoder io.WriteCloser ) @@ -251,7 +257,7 @@ func (mfs *MemFS) ContentEncode(encoding string) (err error) { case EncodingGzip: encoder = gzip.NewWriter(&buf) default: - return fmt.Errorf("memfs.ContentEncode: invalid encoding " + encoding) + return fmt.Errorf("%s: invalid encoding %q", logp, encoding) } nodes := mfs.PathNodes.Nodes() @@ -262,12 +268,12 @@ func (mfs *MemFS) ContentEncode(encoding string) (err error) { _, err = encoder.Write(node.Content) if err != nil { - return fmt.Errorf("memfs.ContentEncode: %w", err) + return fmt.Errorf("%s: %w", logp, err) } err = encoder.Close() if err != nil { - return fmt.Errorf("memfs.ContentEncode: %w", err) + return fmt.Errorf("%s: %w", logp, err) } node.Content = make([]byte, buf.Len()) @@ -292,13 +298,14 @@ func (mfs *MemFS) ContentEncode(encoding string) (err error) { // will return os.ErrNotExist. // func (mfs *MemFS) Get(path string) (node *Node, err error) { + logp := "Get" + node = mfs.PathNodes.Get(path) if node == nil { if mfs.Opts.Development { node, err = mfs.refresh(path) if err != nil { - log.Println("lib/memfs: Get: " + err.Error()) - return nil, fmt.Errorf("memfs.Get: %w", os.ErrNotExist) + return nil, fmt.Errorf("%s: %s: %w", logp, path, err) } return node, nil } @@ -308,7 +315,7 @@ func (mfs *MemFS) Get(path string) (node *Node, err error) { if mfs.Opts.Development { err = node.Update(nil, mfs.Opts.MaxFileSize) if err != nil { - return nil, fmt.Errorf("memfs.Get: %w", err) + return nil, fmt.Errorf("%s: %s: %w", logp, path, err) } } @@ -389,6 +396,11 @@ func (mfs *MemFS) Search(words []string, snippetLen int) (results []SearchResult snippetLen = 60 } + var ( + logp = "Search" + err error + ) + tokens := libstrings.ToBytes(words) for x := 0; x < len(tokens); x++ { tokens[x] = bytes.ToLower(tokens[x]) @@ -405,9 +417,9 @@ func (mfs *MemFS) Search(words []string, snippetLen int) (results []SearchResult } if len(node.lowerv) == 0 { - _, err := node.Decode() + _, err = node.Decode() if err != nil { - log.Printf("memfs.Search: " + err.Error()) + log.Printf("%s: %s", logp, err) continue } @@ -457,20 +469,20 @@ func (mfs *MemFS) Update(node *Node, newInfo os.FileInfo) { err := node.Update(newInfo, mfs.Opts.MaxFileSize) if err != nil { - log.Printf("MemFS.Update: %s", err) + log.Printf("Update: %s: %s", node.SysPath, err) } } func (mfs *MemFS) createRoot() error { - logp := fmt.Sprintf("createRoot %s", mfs.Opts.Root) + logp := "createRoot" fi, err := os.Stat(mfs.Opts.Root) if err != nil { - return fmt.Errorf("%s: %w", logp, err) + return fmt.Errorf("%s: %s: %w", logp, mfs.Opts.Root, err) } if !fi.IsDir() { - return fmt.Errorf("%s: must be a directory", logp) + return fmt.Errorf("%s: %s must be a directory", logp, mfs.Opts.Root) } mfs.Root = &Node{ @@ -545,6 +557,8 @@ func (mfs *MemFS) mount() (err error) { return nil } + logp := "mount" + if mfs.PathNodes == nil { mfs.PathNodes = &PathNode{ v: make(map[string]*Node), @@ -554,12 +568,12 @@ func (mfs *MemFS) mount() (err error) { err = mfs.createRoot() if err != nil { - return fmt.Errorf("mount: %w", err) + return fmt.Errorf("%s: %w", logp, err) } _, err = mfs.scanDir(mfs.Root) if err != nil { - return fmt.Errorf("mount: %w", err) + return fmt.Errorf("%s: %w", logp, err) } return nil @@ -580,12 +594,12 @@ func (mfs *MemFS) scanDir(node *Node) (n int, err error) { f, err = os.Open(node.SysPath) if err != nil { - return 0, fmt.Errorf("%s: %w", logp, err) + return 0, fmt.Errorf("%s: %s: %w", logp, node.SysPath, err) } fis, err = f.Readdir(0) if err != nil { - return 0, fmt.Errorf("%s: %w", logp, err) + return 0, fmt.Errorf("%s: %s: %w", logp, node.SysPath, err) } sort.SliceStable(fis, func(x, y int) bool { @@ -595,7 +609,7 @@ func (mfs *MemFS) scanDir(node *Node) (n int, err error) { for _, fi = range fis { child, err = mfs.AddChild(node, fi) if err != nil { - err = fmt.Errorf("%s: %w", logp, err) + err = fmt.Errorf("%s: %s: %w", logp, node.SysPath, err) goto out } if child == nil { @@ -608,7 +622,7 @@ func (mfs *MemFS) scanDir(node *Node) (n int, err error) { nchilds, err = mfs.scanDir(child) if err != nil { - err = fmt.Errorf("%s: %w", logp, err) + err = fmt.Errorf("%s: %s: %w", logp, node.SysPath, err) goto out } if nchilds == 0 { @@ -621,9 +635,9 @@ out: errClose := f.Close() if errClose != nil { if err == nil { - err = fmt.Errorf("%s: %w", logp, errClose) + err = fmt.Errorf("%s: %s: %w", logp, node.SysPath, errClose) } else { - log.Printf("%s: %s", logp, errClose) + log.Printf("%s: %s: %s", logp, node.SysPath, errClose) } } @@ -634,16 +648,17 @@ out: // refresh the tree by rescanning from the root. // func (mfs *MemFS) refresh(url string) (node *Node, err error) { + logp := "refresh" syspath := filepath.Join(mfs.Root.SysPath, url) _, err = os.Stat(syspath) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %s: %w", logp, url, err) } _, err = mfs.scanDir(mfs.Root) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %s: %w", logp, url, err) } node = mfs.PathNodes.Get(url) diff --git a/lib/memfs/memfs_test.go b/lib/memfs/memfs_test.go index e45fa330..65da48af 100644 --- a/lib/memfs/memfs_test.go +++ b/lib/memfs/memfs_test.go @@ -66,7 +66,7 @@ func TestNew(t *testing.T) { opts: Options{ Root: afile, }, - expErr: fmt.Sprintf("memfs.New: mount: createRoot %s: must be a directory", afile), + expErr: fmt.Sprintf("New: mount: createRoot: %s must be a directory", afile), }, { desc: "With directory", opts: Options{ @@ -139,14 +139,16 @@ func TestNew(t *testing.T) { }} for _, c := range cases { + t.Log(c.desc) + mfs, err := New(&c.opts) if err != nil { - test.Assert(t, c.desc+": error", c.expErr, err.Error()) + test.Assert(t, "error", c.expErr, err.Error()) continue } gotListNames := mfs.ListNames() - test.Assert(t, c.desc+": names", c.expMapKeys, gotListNames) + test.Assert(t, "ListNames", c.expMapKeys, gotListNames) } } @@ -163,7 +165,7 @@ func TestMemFS_AddFile(t *testing.T) { desc: "With external path is not exist", intPath: "internal/file", extPath: "is/not/exist", - expError: "memfs.AddFile: stat is/not/exist: no such file or directory", + expError: "AddFile: stat is/not/exist: no such file or directory", }, { desc: "With file exist", intPath: "internal/file", @@ -201,9 +203,11 @@ func TestMemFS_AddFile(t *testing.T) { } for _, c := range cases { + t.Log(c.desc) + got, err := mfs.AddFile(c.intPath, c.extPath) if err != nil { - test.Assert(t, c.desc+": error", c.expError, err.Error()) + test.Assert(t, "error", c.expError, err.Error()) continue } diff --git a/lib/memfs/node.go b/lib/memfs/node.go index 3cbd22ac..cbca6983 100644 --- a/lib/memfs/node.go +++ b/lib/memfs/node.go @@ -152,12 +152,13 @@ func (node *Node) Decode() ([]byte, error) { return node.plainv, nil } + logp := "Decode" node.plainv = node.plainv[:0] if node.ContentEncoding == EncodingGzip { r, err := gzip.NewReader(bytes.NewReader(node.Content)) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %w", logp, err) } buf := make([]byte, 1024) @@ -170,7 +171,7 @@ func (node *Node) Decode() ([]byte, error) { if err == io.EOF { break } - return nil, err + return nil, fmt.Errorf("%s: %w", logp, err) } buf = buf[0:] } @@ -183,7 +184,7 @@ func (node *Node) Decode() ([]byte, error) { // Encode compress and set the content of Node. // func (node *Node) Encode(content []byte) (err error) { - logp := "Node.Encode" + logp := "Encode" node.plainv = content node.lowerv = bytes.ToLower(content) @@ -250,7 +251,7 @@ func (node *Node) Read(p []byte) (n int, err error) { return 0, nil } if node.off >= node.size { - return 0, io.EOF + return 0, fmt.Errorf("Read: %w", io.EOF) } n = copy(p, node.Content[node.off:]) node.off += int64(n) @@ -300,7 +301,7 @@ func (node *Node) Readdir(count int) (fis []os.FileInfo, err error) { // func (node *Node) Save(content []byte) (err error) { var ( - logp = "Node.Save" + logp = "Save" f *os.File ) f, err = os.OpenFile(node.SysPath, os.O_WRONLY|os.O_TRUNC, node.mode.Perm()) @@ -414,7 +415,7 @@ func (node *Node) addChild( ) (child *Node, err error) { child, err = NewNode(node, fi, maxFileSize) if err != nil { - return nil, err + return nil, fmt.Errorf("addChild: %w", err) } child.SysPath = sysPath @@ -434,19 +435,19 @@ func (node *Node) packAsJson(buf *bytes.Buffer, depth int) { _ = buf.WriteByte('{') - _, _ = fmt.Fprintf(buf, `%q:%q,`, "path", node.Path) - _, _ = fmt.Fprintf(buf, `%q:%q,`, "name", node.name) - _, _ = fmt.Fprintf(buf, `%q:%q,`, "content_type", node.ContentType) - _, _ = fmt.Fprintf(buf, `%q:%d,`, "mod_time", node.modTime.Unix()) - _, _ = fmt.Fprintf(buf, `%q:%q,`, "mode_string", node.mode) - _, _ = fmt.Fprintf(buf, `%q:%d,`, "size", node.size) - _, _ = fmt.Fprintf(buf, `%q:%t,`, "is_dir", isDir) + _, _ = fmt.Fprintf(buf, `"path":%q,`, node.Path) + _, _ = fmt.Fprintf(buf, `"name":%q,`, node.name) + _, _ = fmt.Fprintf(buf, `"content_type":%q,`, node.ContentType) + _, _ = fmt.Fprintf(buf, `"mod_time":%d,`, node.modTime.Unix()) + _, _ = fmt.Fprintf(buf, `"mode_string":%q,`, node.mode) + _, _ = fmt.Fprintf(buf, `"size":%d,`, node.size) + _, _ = fmt.Fprintf(buf, `"is_dir":%t,`, isDir) if !isDir && depth == 0 { content := base64.StdEncoding.EncodeToString(node.Content) - _, _ = fmt.Fprintf(buf, `%q:%q,`, "content", content) + _, _ = fmt.Fprintf(buf, `"content":%q,`, content) } - _, _ = fmt.Fprintf(buf, `%q:`, "childs") + _, _ = fmt.Fprintf(buf, `"childs":`) if depth == 0 { _ = buf.WriteByte('[') for x, child := range node.Childs { @@ -512,10 +513,12 @@ func (node *Node) resetAllModTime(t time.Time) { // Change on mode will not affect the content of node. // func (node *Node) Update(newInfo os.FileInfo, maxFileSize int64) (err error) { + logp := "Update" + if newInfo == nil { newInfo, err = os.Stat(node.SysPath) if err != nil { - return fmt.Errorf("Node.Update: %q: %w", node.Path, err) + return fmt.Errorf("%s: %s: %w", logp, node.SysPath, err) } } @@ -533,7 +536,7 @@ func (node *Node) Update(newInfo os.FileInfo, maxFileSize int64) (err error) { err = node.updateContent(maxFileSize) if err != nil { - return fmt.Errorf("Node.Update: %q: %w", node.Path, err) + return fmt.Errorf("%s: %s: %w", logp, node.SysPath, err) } return nil } @@ -561,7 +564,7 @@ func (node *Node) updateContent(maxFileSize int64) (err error) { if errors.Is(err, io.EOF) { return nil } - return err + return fmt.Errorf("updateContent: %w", err) } return nil @@ -584,6 +587,7 @@ func (node *Node) updateContentType() error { return nil } + logp := "updateContentType" data := make([]byte, 512) f, err := os.Open(node.SysPath) @@ -593,7 +597,7 @@ func (node *Node) updateContentType() error { node.ContentType = defContentType return nil } - return err + return fmt.Errorf("%s: %w", logp, err) } _, err = f.Read(data) @@ -602,11 +606,12 @@ func (node *Node) updateContentType() error { if errc != nil { panic(errc) } - return err + return fmt.Errorf("%s: %w", logp, err) } err = f.Close() if err != nil { + err = fmt.Errorf("%s: %w", logp, err) panic(err) } diff --git a/lib/memfs/node_test.go b/lib/memfs/node_test.go index ed5e2c50..271bcbaa 100644 --- a/lib/memfs/node_test.go +++ b/lib/memfs/node_test.go @@ -27,7 +27,7 @@ func TestNode_Read(t *testing.T) { p []byte exp []byte expN int - expError error + expError string }{{ desc: "With empty p", }, { @@ -50,7 +50,7 @@ func TestNode_Read(t *testing.T) { p: p, exp: []byte(`3`), expN: 0, - expError: io.EOF, + expError: "Read: EOF", }} for _, c := range cases { @@ -60,7 +60,10 @@ func TestNode_Read(t *testing.T) { test.Assert(t, "p", c.exp, c.p) test.Assert(t, "n", c.expN, n) - test.Assert(t, "error", c.expError, err) + + if err != nil { + test.Assert(t, "error", c.expError, err.Error()) + } } } |
