Skip to content

Commit

Permalink
repository: optimize error handing if root.json fails to load
Browse files Browse the repository at this point in the history
  • Loading branch information
AstroProfundis committed Apr 13, 2021
1 parent 3366472 commit e87f392
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 1 deletion.
7 changes: 7 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@
package cmd

import (
"errors"
"fmt"
"os"

"github.com/fatih/color"
perrs "github.com/pingcap/errors"
"github.com/pingcap/tiup/pkg/environment"
"github.com/pingcap/tiup/pkg/exec"
"github.com/pingcap/tiup/pkg/localdata"
"github.com/pingcap/tiup/pkg/logger/log"
"github.com/pingcap/tiup/pkg/repository"
"github.com/pingcap/tiup/pkg/repository/v1manifest"
"github.com/pingcap/tiup/pkg/version"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -69,6 +73,9 @@ the latest stable version will be downloaded from the repository.`,
default:
e, err := environment.InitEnv(repoOpts)
if err != nil {
if errors.Is(perrs.Cause(err), v1manifest.ErrLoadManifest) {
log.Warnf("Please check for root manifest file, you may download one from the repository mirror, or try `tiup mirror set` to force reset it.")
}
return err
}
environment.SetGlobalEnv(e)
Expand Down
5 changes: 4 additions & 1 deletion pkg/repository/v1manifest/local_manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,10 @@ func (ms *FsManifests) load(filename string) (string, error) {
}
bytes, err := os.ReadFile(initRoot)
if err != nil {
return "", errors.Errorf("cannot open the initial root.json at %s", initRoot)
return "", &LoadManifestError{
manifest: "root.json",
err: err,
}
}
return string(bytes), nil
}
Expand Down
33 changes: 33 additions & 0 deletions pkg/repository/v1manifest/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ package v1manifest

import (
"encoding/json"
"errors"
"fmt"
"time"
)

Expand Down Expand Up @@ -269,3 +271,34 @@ func (manifest *Component) VersionListWithYanked(platform string) map[string]Ver

return vs
}

// ErrLoadManifest is an empty object of LoadManifestError, useful for type check
var ErrLoadManifest = &LoadManifestError{}

// LoadManifestError is the error type used when loading manifest failes
type LoadManifestError struct {
manifest string // manifest name
err error // wrapped error
}

// Error implements the error interface
func (e *LoadManifestError) Error() string {
return fmt.Sprintf(
"error loading manifest %s: %s",
e.manifest, e.err,
)
}

// Unwrap implements the error interface
func (e *LoadManifestError) Unwrap() error { return e.err }

// Is implements the error interface
func (e *LoadManifestError) Is(target error) bool {
t, ok := target.(*LoadManifestError)
if !ok {
return false
}

return (e.manifest == t.manifest || t.manifest == "") &&
(errors.Is(e.err, t) || t.err == nil)
}
36 changes: 36 additions & 0 deletions pkg/repository/v1manifest/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
package v1manifest

import (
"errors"
"fmt"
"testing"

"github.com/alecthomas/assert"
Expand Down Expand Up @@ -83,3 +85,37 @@ func TestVersionList(t *testing.T) {
versions = manifest.VersionList("windows/amd64")
assert.Equal(t, len(versions), 0)
}

func TestLoadManifestError(t *testing.T) {
err0 := &LoadManifestError{
manifest: "root.json",
err: fmt.Errorf("dummy error"),
}
// identical errors are equal
assert.True(t, errors.Is(err0, err0))
assert.True(t, errors.Is(ErrLoadManifest, ErrLoadManifest))
assert.True(t, errors.Is(ErrLoadManifest, &LoadManifestError{}))
assert.True(t, errors.Is(&LoadManifestError{}, ErrLoadManifest))
// not equal for different error types
assert.False(t, errors.Is(err0, errors.New("")))
// default Value matches any error
assert.True(t, errors.Is(err0, ErrLoadManifest))
// error with values are not matching default ones
assert.False(t, errors.Is(ErrLoadManifest, err0))

err1 := &LoadManifestError{
manifest: "root.json",
err: fmt.Errorf("dummy error 2"),
}
assert.True(t, errors.Is(err1, ErrLoadManifest))
// errors with different errors are different
assert.False(t, errors.Is(err0, err1))
assert.False(t, errors.Is(err1, err0))

err2 := &LoadManifestError{
manifest: "root.json",
}
// nil errors can be match with any error, but not vise vera
assert.True(t, errors.Is(err1, err2))
assert.False(t, errors.Is(err2, err1))
}

0 comments on commit e87f392

Please sign in to comment.