Merge pull request #189 from safing/fix/fs-error-handling

Fix fs error handling
This commit is contained in:
Daniel Hovie 2022-10-11 12:45:29 +02:00 committed by GitHub
commit 985a174aff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 25 additions and 15 deletions

View file

@ -5,6 +5,7 @@ import (
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@ -63,12 +64,12 @@ func start() error {
} }
err = registerAsDatabase() err = registerAsDatabase()
if err != nil && !os.IsNotExist(err) { if err != nil && !errors.Is(err, fs.ErrNotExist) {
return err return err
} }
err = loadConfig(false) err = loadConfig(false)
if err != nil && !os.IsNotExist(err) { if err != nil && !errors.Is(err, fs.ErrNotExist) {
return err return err
} }
return nil return nil

View file

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/fs"
"os" "os"
"path" "path"
"regexp" "regexp"
@ -116,7 +117,7 @@ func loadRegistry() error {
filePath := path.Join(rootStructure.Path, registryFileName) filePath := path.Join(rootStructure.Path, registryFileName)
data, err := os.ReadFile(filePath) data, err := os.ReadFile(filePath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if errors.Is(err, fs.ErrNotExist) {
return nil return nil
} }
return err return err

View file

@ -8,6 +8,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -46,7 +47,7 @@ func NewFSTree(name, location string) (storage.Interface, error) {
file, err := os.Stat(basePath) file, err := os.Stat(basePath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if errors.Is(err, fs.ErrNotExist) {
err = os.MkdirAll(basePath, defaultDirMode) err = os.MkdirAll(basePath, defaultDirMode)
if err != nil { if err != nil {
return nil, fmt.Errorf("fstree: failed to create directory %s: %w", basePath, err) return nil, fmt.Errorf("fstree: failed to create directory %s: %w", basePath, err)
@ -89,7 +90,7 @@ func (fst *FSTree) Get(key string) (record.Record, error) {
data, err := os.ReadFile(dstPath) data, err := os.ReadFile(dstPath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if errors.Is(err, fs.ErrNotExist) {
return nil, storage.ErrNotFound return nil, storage.ErrNotFound
} }
return nil, fmt.Errorf("fstree: failed to read file %s: %w", dstPath, err) return nil, fmt.Errorf("fstree: failed to read file %s: %w", dstPath, err)
@ -176,7 +177,7 @@ func (fst *FSTree) Query(q *query.Query, local, internal bool) (*iterator.Iterat
walkRoot = walkPrefix walkRoot = walkPrefix
case err == nil: case err == nil:
walkRoot = filepath.Dir(walkPrefix) walkRoot = filepath.Dir(walkPrefix)
case os.IsNotExist(err): case errors.Is(err, fs.ErrNotExist):
walkRoot = filepath.Dir(walkPrefix) walkRoot = filepath.Dir(walkPrefix)
default: // err != nil default: // err != nil
return nil, fmt.Errorf("fstree: could not stat query root %s: %w", walkPrefix, err) return nil, fmt.Errorf("fstree: could not stat query root %s: %w", walkPrefix, err)
@ -211,7 +212,7 @@ func (fst *FSTree) queryExecutor(walkRoot string, queryIter *iterator.Iterator,
// read file // read file
data, err := os.ReadFile(path) data, err := os.ReadFile(path)
if err != nil { if err != nil {
if os.IsNotExist(err) { if errors.Is(err, fs.ErrNotExist) {
return nil return nil
} }
return fmt.Errorf("fstree: failed to read file %s: %w", path, err) return fmt.Errorf("fstree: failed to read file %s: %w", path, err)
@ -274,7 +275,7 @@ func (fst *FSTree) Shutdown() error {
return nil return nil
} }
// writeFile mirrors ioutil.WriteFile, replacing an existing file with the same // writeFile mirrors os.WriteFile, replacing an existing file with the same
// name atomically. This is not atomic on Windows, but still an improvement. // name atomically. This is not atomic on Windows, but still an improvement.
// TODO: Replace with github.com/google/renamio.WriteFile as soon as it is fixed on Windows. // TODO: Replace with github.com/google/renamio.WriteFile as soon as it is fixed on Windows.
// TODO: This has become a wont-fix. Explore other options. // TODO: This has become a wont-fix. Explore other options.

View file

@ -1,7 +1,9 @@
package updater package updater
import ( import (
"errors"
"io" "io"
"io/fs"
"os" "os"
"strings" "strings"
@ -121,7 +123,7 @@ func (file *File) Unpack(suffix string, unpacker Unpacker) (string, error) {
return path, nil return path, nil
} }
if !os.IsNotExist(err) { if !errors.Is(err, fs.ErrNotExist) {
return "", err return "", err
} }

View file

@ -489,7 +489,7 @@ boundarySearch:
// Remove if it exists, or an error occurs on access. // Remove if it exists, or an error occurs on access.
_, err = os.Stat(unpackedPath) _, err = os.Stat(unpackedPath)
if err == nil || !os.IsNotExist(err) { if err == nil || !errors.Is(err, fs.ErrNotExist) {
err = os.Remove(unpackedPath) err = os.Remove(unpackedPath)
if err != nil { if err != nil {
log.Warningf("%s: failed to purge unpacked resource %s v%s: %s", res.registry.Name, rv.resource.Identifier, rv.VersionNumber, err) log.Warningf("%s: failed to purge unpacked resource %s v%s: %s", res.registry.Name, rv.resource.Identifier, rv.VersionNumber, err)

View file

@ -6,6 +6,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/fs"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -88,7 +89,7 @@ func (res *Resource) unpackZipArchive() error {
// Check status of destination. // Check status of destination.
dstStat, err := os.Stat(destDir) dstStat, err := os.Stat(destDir)
switch { switch {
case os.IsNotExist(err): case errors.Is(err, fs.ErrNotExist):
// The destination does not exist, continue with unpacking. // The destination does not exist, continue with unpacking.
case err != nil: case err != nil:
return fmt.Errorf("cannot access destination for unpacking: %w", err) return fmt.Errorf("cannot access destination for unpacking: %w", err)

View file

@ -1,8 +1,10 @@
package utils package utils
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"io/fs"
"os" "os"
"github.com/safing/portbase/utils/renameio" "github.com/safing/portbase/utils/renameio"
@ -94,7 +96,7 @@ func ReplaceFileAtomic(dest string, src string, opts *AtomicFileOptions) error {
stat, err := os.Stat(dest) stat, err := os.Stat(dest)
if err == nil { if err == nil {
opts.Mode = stat.Mode() opts.Mode = stat.Mode()
} else if !os.IsNotExist(err) { } else if !errors.Is(err, fs.ErrNotExist) {
return err return err
} }
} }

View file

@ -33,7 +33,7 @@ func EnsureDirectory(path string, perm os.FileMode) error {
} }
} }
// file does not exist (or has been deleted) // file does not exist (or has been deleted)
if err == nil || os.IsNotExist(err) { if err == nil || errors.Is(err, fs.ErrNotExist) {
err = os.Mkdir(path, perm) err = os.Mkdir(path, perm)
if err != nil { if err != nil {
return fmt.Errorf("could not create dir %s: %w", path, err) return fmt.Errorf("could not create dir %s: %w", path, err)

View file

@ -1,6 +1,8 @@
package renameio package renameio
import ( import (
"errors"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
) )
@ -137,7 +139,7 @@ func TempFile(dir, path string) (*PendingFile, error) {
func Symlink(oldname, newname string) error { func Symlink(oldname, newname string) error {
// Fast path: if newname does not exist yet, we can skip the whole dance // Fast path: if newname does not exist yet, we can skip the whole dance
// below. // below.
if err := os.Symlink(oldname, newname); err == nil || !os.IsExist(err) { if err := os.Symlink(oldname, newname); err == nil || !errors.Is(err, fs.ErrExist) {
return err return err
} }

View file

@ -2,7 +2,7 @@ package renameio
import "os" import "os"
// WriteFile mirrors ioutil.WriteFile, replacing an existing file with the same // WriteFile mirrors os.WriteFile, replacing an existing file with the same
// name atomically. // name atomically.
func WriteFile(filename string, data []byte, perm os.FileMode) error { func WriteFile(filename string, data []byte, perm os.FileMode) error {
t, err := TempFile("", filename) t, err := TempFile("", filename)