mirror of https://github.com/docker/docs.git
Pass original invalid version storage error details into standardized errors
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
This commit is contained in:
parent
a60f228189
commit
8d0ff6c996
|
@ -44,6 +44,12 @@ var (
|
|||
Description: "An error occurred when attempting to apply an update at the storage layer.",
|
||||
HTTPStatusCode: http.StatusInternalServerError,
|
||||
})
|
||||
ErrOldVersion = errcode.Register(errGroup, errcode.ErrorDescriptor{
|
||||
Value: "VERSION",
|
||||
Message: "A newer version of metadata is already available.",
|
||||
Description: "A newer version of the repository's metadata is already available in storage.",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
})
|
||||
ErrMetadataNotFound = errcode.Register(errGroup, errcode.ErrorDescriptor{
|
||||
Value: "METADATA_NOT_FOUND",
|
||||
Message: "You have requested metadata that does not exist.",
|
||||
|
|
|
@ -96,6 +96,11 @@ func atomicUpdateHandler(ctx context.Context, w http.ResponseWriter, r *http.Req
|
|||
}
|
||||
err = store.UpdateMany(gun, updates)
|
||||
if err != nil {
|
||||
// If we have an old version error, surface to user with error code
|
||||
if _, ok := err.(storage.ErrOldVersion); ok {
|
||||
return errors.ErrOldVersion.WithDetail(err)
|
||||
}
|
||||
// More generic storage update error, possibly due to attempted rollback
|
||||
return errors.ErrUpdating.WithDetail(nil)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -385,3 +385,43 @@ func TestAtomicUpdateNonValidationFailureNotPropagated(t *testing.T) {
|
|||
assert.Equal(t, errors.ErrInvalidUpdate, errorObj.Code)
|
||||
assert.Nil(t, errorObj.Detail)
|
||||
}
|
||||
|
||||
type invalidVersionStore struct {
|
||||
storage.MemStorage
|
||||
}
|
||||
|
||||
func (s *invalidVersionStore) UpdateMany(_ string, _ []storage.MetaUpdate) error {
|
||||
return storage.ErrOldVersion{}
|
||||
}
|
||||
|
||||
// a non-validation failure, such as the storage failing, will be propagated
|
||||
// as a detail in the error (which gets serialized as the body of the response)
|
||||
func TestAtomicUpdateVersionErrorPropagated(t *testing.T) {
|
||||
metaStore := storage.NewMemStorage()
|
||||
gun := "testGUN"
|
||||
vars := map[string]string{"imageName": gun}
|
||||
|
||||
kdb, repo, cs := testutils.EmptyRepo()
|
||||
copyTimestampKey(t, kdb, metaStore, gun)
|
||||
state := handlerState{store: &invalidVersionStore{*metaStore}, crypto: cs}
|
||||
|
||||
r, tg, sn, ts, err := testutils.Sign(repo)
|
||||
assert.NoError(t, err)
|
||||
rs, tgs, sns, _, err := testutils.Serialize(r, tg, sn, ts)
|
||||
assert.NoError(t, err)
|
||||
|
||||
req, err := store.NewMultiPartMetaRequest("", map[string][]byte{
|
||||
data.CanonicalRootRole: rs,
|
||||
data.CanonicalTargetsRole: tgs,
|
||||
data.CanonicalSnapshotRole: sns,
|
||||
})
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
|
||||
err = atomicUpdateHandler(getContext(state), rw, req, vars)
|
||||
assert.Error(t, err)
|
||||
errorObj, ok := err.(errcode.Error)
|
||||
assert.True(t, ok, "Expected an errcode.Error, got %v", err)
|
||||
assert.Equal(t, errors.ErrOldVersion, errorObj.Code)
|
||||
assert.Equal(t, storage.ErrOldVersion{}, errorObj.Detail)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue