forked from TrueCloudLab/distribution
Add a generic error type to capture non-typed errors
Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
This commit is contained in:
parent
7840a5bc8f
commit
e79324edd8
10 changed files with 44 additions and 29 deletions
|
@ -36,15 +36,15 @@ func (bs *blobServer) ServeBlob(ctx context.Context, w http.ResponseWriter, r *h
|
|||
|
||||
redirectURL, err := bs.driver.URLFor(ctx, path, map[string]interface{}{"method": r.Method})
|
||||
|
||||
if err == nil {
|
||||
switch err.(type) {
|
||||
case nil:
|
||||
if bs.redirect {
|
||||
// Redirect to storage URL.
|
||||
http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := err.(*driver.ErrUnsupportedMethod); ok {
|
||||
case driver.ErrUnsupportedMethod:
|
||||
// Fallback to serving the content directly.
|
||||
br, err := newFileReader(ctx, bs.driver, path, desc.Size)
|
||||
if err != nil {
|
||||
|
|
|
@ -52,25 +52,29 @@ type Base struct {
|
|||
|
||||
// Format errors received from the storage driver
|
||||
func (base *Base) setDriverName(e error) error {
|
||||
if e != nil {
|
||||
if actualErr, ok := e.(storagedriver.ErrUnsupportedMethod); ok {
|
||||
actualErr.DriverName = base.StorageDriver.Name()
|
||||
return actualErr
|
||||
switch actual := e.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case storagedriver.ErrUnsupportedMethod:
|
||||
actual.DriverName = base.StorageDriver.Name()
|
||||
return actual
|
||||
case storagedriver.PathNotFoundError:
|
||||
actual.DriverName = base.StorageDriver.Name()
|
||||
return actual
|
||||
case storagedriver.InvalidPathError:
|
||||
actual.DriverName = base.StorageDriver.Name()
|
||||
return actual
|
||||
case storagedriver.InvalidOffsetError:
|
||||
actual.DriverName = base.StorageDriver.Name()
|
||||
return actual
|
||||
default:
|
||||
storageError := storagedriver.Error{
|
||||
DriverName: base.StorageDriver.Name(),
|
||||
Enclosed: e,
|
||||
}
|
||||
if actualErr, ok := e.(storagedriver.PathNotFoundError); ok {
|
||||
actualErr.DriverName = base.StorageDriver.Name()
|
||||
return actualErr
|
||||
|
||||
return storageError
|
||||
}
|
||||
if actualErr, ok := e.(storagedriver.InvalidPathError); ok {
|
||||
actualErr.DriverName = base.StorageDriver.Name()
|
||||
return actualErr
|
||||
}
|
||||
if actualErr, ok := e.(storagedriver.InvalidOffsetError); ok {
|
||||
actualErr.DriverName = base.StorageDriver.Name()
|
||||
return actualErr
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// GetContent wraps GetContent of underlying storage driver.
|
||||
|
|
|
@ -248,7 +248,7 @@ func (d *driver) Delete(ctx context.Context, subPath string) error {
|
|||
// URLFor returns a URL which may be used to retrieve the content stored at the given path.
|
||||
// May return an UnsupportedMethodErr in certain StorageDriver implementations.
|
||||
func (d *driver) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) {
|
||||
return "", new(storagedriver.ErrUnsupportedMethod)
|
||||
return "", storagedriver.ErrUnsupportedMethod{}
|
||||
}
|
||||
|
||||
// fullPath returns the absolute path of a key within the Driver's storage.
|
||||
|
|
|
@ -575,7 +575,7 @@ func (d *driver) Delete(context ctx.Context, path string) error {
|
|||
// Returns ErrUnsupportedMethod if this driver has no privateKey
|
||||
func (d *driver) URLFor(context ctx.Context, path string, options map[string]interface{}) (string, error) {
|
||||
if d.privateKey == nil {
|
||||
return "", storagedriver.ErrUnsupportedMethod
|
||||
return "", storagedriver.ErrUnsupportedMethod{}
|
||||
}
|
||||
|
||||
name := d.pathToKey(path)
|
||||
|
@ -584,7 +584,7 @@ func (d *driver) URLFor(context ctx.Context, path string, options map[string]int
|
|||
if ok {
|
||||
methodString, ok = method.(string)
|
||||
if !ok || (methodString != "GET" && methodString != "HEAD") {
|
||||
return "", storagedriver.ErrUnsupportedMethod
|
||||
return "", storagedriver.ErrUnsupportedMethod{}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -258,5 +258,5 @@ func (d *driver) Delete(ctx context.Context, path string) error {
|
|||
// URLFor returns a URL which may be used to retrieve the content stored at the given path.
|
||||
// May return an UnsupportedMethodErr in certain StorageDriver implementations.
|
||||
func (d *driver) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) {
|
||||
return "", new(storagedriver.ErrUnsupportedMethod)
|
||||
return "", storagedriver.ErrUnsupportedMethod{}
|
||||
}
|
||||
|
|
|
@ -748,7 +748,7 @@ func (d *driver) URLFor(ctx context.Context, path string, options map[string]int
|
|||
if ok {
|
||||
methodString, ok = method.(string)
|
||||
if !ok || (methodString != "GET" && methodString != "HEAD") {
|
||||
return "", new(storagedriver.ErrUnsupportedMethod)
|
||||
return "", storagedriver.ErrUnsupportedMethod{}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -496,7 +496,7 @@ func (d *driver) Delete(ctx context.Context, objectPath string) error {
|
|||
// URLFor returns a URL which may be used to retrieve the content stored at the given path.
|
||||
// May return an UnsupportedMethodErr in certain StorageDriver implementations.
|
||||
func (d *driver) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) {
|
||||
return "", new(storagedriver.ErrUnsupportedMethod)
|
||||
return "", storagedriver.ErrUnsupportedMethod{}
|
||||
}
|
||||
|
||||
// Generate a blob identifier
|
||||
|
|
|
@ -759,7 +759,7 @@ func (d *driver) URLFor(ctx context.Context, path string, options map[string]int
|
|||
if ok {
|
||||
methodString, ok = method.(string)
|
||||
if !ok || (methodString != "GET" && methodString != "HEAD") {
|
||||
return "", new(storagedriver.ErrUnsupportedMethod)
|
||||
return "", storagedriver.ErrUnsupportedMethod{}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,3 +131,14 @@ type InvalidOffsetError struct {
|
|||
func (err InvalidOffsetError) Error() string {
|
||||
return fmt.Sprintf("[%s] Invalid offset: %d for path: %s", err.DriverName, err.Offset, err.Path)
|
||||
}
|
||||
|
||||
// Error is a catch-all error type which captures an error string and
|
||||
// the driver type on which it occured.
|
||||
type Error struct {
|
||||
DriverName string
|
||||
Enclosed error
|
||||
}
|
||||
|
||||
func (err Error) Error() string {
|
||||
return fmt.Sprintf("[%s] %s", err.DriverName, err.Enclosed)
|
||||
}
|
||||
|
|
|
@ -626,7 +626,7 @@ func (suite *DriverSuite) TestURLFor(c *check.C) {
|
|||
c.Assert(err, check.IsNil)
|
||||
|
||||
url, err := suite.StorageDriver.URLFor(suite.ctx, filename, nil)
|
||||
if _, ok := err.(*storagedriver.ErrUnsupportedMethod); ok {
|
||||
if _, ok := err.(storagedriver.ErrUnsupportedMethod); ok {
|
||||
return
|
||||
}
|
||||
c.Assert(err, check.IsNil)
|
||||
|
@ -640,7 +640,7 @@ func (suite *DriverSuite) TestURLFor(c *check.C) {
|
|||
c.Assert(read, check.DeepEquals, contents)
|
||||
|
||||
url, err = suite.StorageDriver.URLFor(suite.ctx, filename, map[string]interface{}{"method": "HEAD"})
|
||||
if _, ok := err.(*storagedriver.ErrUnsupportedMethod); ok {
|
||||
if _, ok := err.(storagedriver.ErrUnsupportedMethod); ok {
|
||||
return
|
||||
}
|
||||
c.Assert(err, check.IsNil)
|
||||
|
|
Loading…
Reference in a new issue