1
0
mirror of https://github.com/distribution/distribution synced 2024-11-06 19:35:52 +01:00

refactor: Storage driver errors (#4108)

This commit is contained in:
Wang Yan 2023-10-19 01:12:14 +08:00 committed by GitHub
commit d24243730f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 111 additions and 11 deletions

@ -79,12 +79,10 @@ func (base *Base) setDriverName(e error) error {
actual.DriverName = base.StorageDriver.Name()
return actual
default:
storageError := storagedriver.Error{
return storagedriver.Error{
DriverName: base.StorageDriver.Name(),
Enclosed: e,
Detail: e,
}
return storageError
}
}

@ -0,0 +1,80 @@
package driver
import (
"encoding/json"
"errors"
"fmt"
"testing"
)
func TestErrorFormat(t *testing.T) {
drvName := "foo"
errMsg := "unexpected error"
e := Error{
DriverName: drvName,
Detail: errors.New(errMsg),
}
exp := fmt.Sprintf("%s: %s", drvName, errMsg)
if e.Error() != exp {
t.Errorf("expected: %s, got: %s", exp, e.Error())
}
b, err := json.Marshal(&e)
if err != nil {
t.Fatal(err)
}
expJson := `{"driver":"foo","detail":"unexpected error"}`
if gotJson := string(b); gotJson != expJson {
t.Fatalf("expected JSON: %s,\n got: %s", expJson, gotJson)
}
}
func TestErrors(t *testing.T) {
drvName := "foo"
testCases := []struct {
name string
errs Errors
exp string
expJson string
}{
{
name: "no details",
errs: Errors{DriverName: drvName},
exp: fmt.Sprintf("%s: <nil>", drvName),
expJson: `{"driver":"foo","details":[]}`,
},
{
name: "single detail",
errs: Errors{DriverName: drvName, Errs: []error{errors.New("err msg")}},
exp: fmt.Sprintf("%s: err msg", drvName),
expJson: `{"driver":"foo","details":["err msg"]}`,
},
{
name: "multiple details",
errs: Errors{DriverName: drvName, Errs: []error{errors.New("err msg1"), errors.New("err msg2")}},
exp: fmt.Sprintf("%s: errors:\nerr msg1\nerr msg2\n", drvName),
expJson: `{"driver":"foo","details":["err msg1","err msg2"]}`,
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
if got := tc.errs.Error(); got != tc.exp {
t.Errorf("got error: %s, expected: %s", got, tc.exp)
}
b, err := json.Marshal(&tc.errs)
if err != nil {
t.Fatal(err)
}
if gotJson := string(b); gotJson != tc.expJson {
t.Errorf("expected JSON: %s,\n got: %s", tc.expJson, gotJson)
}
})
}
}

@ -178,20 +178,20 @@ func (err InvalidOffsetError) Error() string {
// the driver type on which it occurred.
type Error struct {
DriverName string
Enclosed error
Detail error
}
func (err Error) Error() string {
return fmt.Sprintf("%s: %s", err.DriverName, err.Enclosed)
return fmt.Sprintf("%s: %s", err.DriverName, err.Detail)
}
func (err Error) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
DriverName string `json:"driver"`
Enclosed string `json:"enclosed"`
Detail string `json:"detail"`
}{
DriverName: err.DriverName,
Enclosed: err.Enclosed.Error(),
Detail: err.Detail.Error(),
})
}
@ -207,14 +207,36 @@ var _ error = Errors{}
func (e Errors) Error() string {
switch len(e.Errs) {
case 0:
return "<nil>"
return fmt.Sprintf("%s: <nil>", e.DriverName)
case 1:
return e.Errs[0].Error()
return fmt.Sprintf("%s: %s", e.DriverName, e.Errs[0].Error())
default:
msg := "errors:\n"
for _, err := range e.Errs {
msg += err.Error() + "\n"
}
return msg
return fmt.Sprintf("%s: %s", e.DriverName, msg)
}
}
// MarshalJSON converts slice of errors into the format
// that is serializable by JSON.
func (e Errors) MarshalJSON() ([]byte, error) {
tmpErrs := struct {
DriverName string `json:"driver"`
Details []string `json:"details"`
}{
DriverName: e.DriverName,
}
if len(e.Errs) == 0 {
tmpErrs.Details = make([]string, 0)
return json.Marshal(tmpErrs)
}
for _, err := range e.Errs {
tmpErrs.Details = append(tmpErrs.Details, err.Error())
}
return json.Marshal(tmpErrs)
}