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})
|
redirectURL, err := bs.driver.URLFor(ctx, path, map[string]interface{}{"method": r.Method})
|
||||||
|
|
||||||
if err == nil {
|
switch err.(type) {
|
||||||
|
case nil:
|
||||||
if bs.redirect {
|
if bs.redirect {
|
||||||
// Redirect to storage URL.
|
// Redirect to storage URL.
|
||||||
http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
|
http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := err.(*driver.ErrUnsupportedMethod); ok {
|
case driver.ErrUnsupportedMethod:
|
||||||
// Fallback to serving the content directly.
|
// Fallback to serving the content directly.
|
||||||
br, err := newFileReader(ctx, bs.driver, path, desc.Size)
|
br, err := newFileReader(ctx, bs.driver, path, desc.Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -52,25 +52,29 @@ type Base struct {
|
||||||
|
|
||||||
// Format errors received from the storage driver
|
// Format errors received from the storage driver
|
||||||
func (base *Base) setDriverName(e error) error {
|
func (base *Base) setDriverName(e error) error {
|
||||||
if e != nil {
|
switch actual := e.(type) {
|
||||||
if actualErr, ok := e.(storagedriver.ErrUnsupportedMethod); ok {
|
case nil:
|
||||||
actualErr.DriverName = base.StorageDriver.Name()
|
return nil
|
||||||
return actualErr
|
case storagedriver.ErrUnsupportedMethod:
|
||||||
}
|
actual.DriverName = base.StorageDriver.Name()
|
||||||
if actualErr, ok := e.(storagedriver.PathNotFoundError); ok {
|
return actual
|
||||||
actualErr.DriverName = base.StorageDriver.Name()
|
case storagedriver.PathNotFoundError:
|
||||||
return actualErr
|
actual.DriverName = base.StorageDriver.Name()
|
||||||
}
|
return actual
|
||||||
if actualErr, ok := e.(storagedriver.InvalidPathError); ok {
|
case storagedriver.InvalidPathError:
|
||||||
actualErr.DriverName = base.StorageDriver.Name()
|
actual.DriverName = base.StorageDriver.Name()
|
||||||
return actualErr
|
return actual
|
||||||
}
|
case storagedriver.InvalidOffsetError:
|
||||||
if actualErr, ok := e.(storagedriver.InvalidOffsetError); ok {
|
actual.DriverName = base.StorageDriver.Name()
|
||||||
actualErr.DriverName = base.StorageDriver.Name()
|
return actual
|
||||||
return actualErr
|
default:
|
||||||
|
storageError := storagedriver.Error{
|
||||||
|
DriverName: base.StorageDriver.Name(),
|
||||||
|
Enclosed: e,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return storageError
|
||||||
}
|
}
|
||||||
return e
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContent wraps GetContent of underlying storage driver.
|
// 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.
|
// 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.
|
// May return an UnsupportedMethodErr in certain StorageDriver implementations.
|
||||||
func (d *driver) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) {
|
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.
|
// 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
|
// Returns ErrUnsupportedMethod if this driver has no privateKey
|
||||||
func (d *driver) URLFor(context ctx.Context, path string, options map[string]interface{}) (string, error) {
|
func (d *driver) URLFor(context ctx.Context, path string, options map[string]interface{}) (string, error) {
|
||||||
if d.privateKey == nil {
|
if d.privateKey == nil {
|
||||||
return "", storagedriver.ErrUnsupportedMethod
|
return "", storagedriver.ErrUnsupportedMethod{}
|
||||||
}
|
}
|
||||||
|
|
||||||
name := d.pathToKey(path)
|
name := d.pathToKey(path)
|
||||||
|
@ -584,7 +584,7 @@ func (d *driver) URLFor(context ctx.Context, path string, options map[string]int
|
||||||
if ok {
|
if ok {
|
||||||
methodString, ok = method.(string)
|
methodString, ok = method.(string)
|
||||||
if !ok || (methodString != "GET" && methodString != "HEAD") {
|
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.
|
// 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.
|
// May return an UnsupportedMethodErr in certain StorageDriver implementations.
|
||||||
func (d *driver) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) {
|
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 {
|
if ok {
|
||||||
methodString, ok = method.(string)
|
methodString, ok = method.(string)
|
||||||
if !ok || (methodString != "GET" && methodString != "HEAD") {
|
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.
|
// 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.
|
// May return an UnsupportedMethodErr in certain StorageDriver implementations.
|
||||||
func (d *driver) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) {
|
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
|
// Generate a blob identifier
|
||||||
|
|
|
@ -759,7 +759,7 @@ func (d *driver) URLFor(ctx context.Context, path string, options map[string]int
|
||||||
if ok {
|
if ok {
|
||||||
methodString, ok = method.(string)
|
methodString, ok = method.(string)
|
||||||
if !ok || (methodString != "GET" && methodString != "HEAD") {
|
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 {
|
func (err InvalidOffsetError) Error() string {
|
||||||
return fmt.Sprintf("[%s] Invalid offset: %d for path: %s", err.DriverName, err.Offset, err.Path)
|
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)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
url, err := suite.StorageDriver.URLFor(suite.ctx, filename, nil)
|
url, err := suite.StorageDriver.URLFor(suite.ctx, filename, nil)
|
||||||
if _, ok := err.(*storagedriver.ErrUnsupportedMethod); ok {
|
if _, ok := err.(storagedriver.ErrUnsupportedMethod); ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
@ -640,7 +640,7 @@ func (suite *DriverSuite) TestURLFor(c *check.C) {
|
||||||
c.Assert(read, check.DeepEquals, contents)
|
c.Assert(read, check.DeepEquals, contents)
|
||||||
|
|
||||||
url, err = suite.StorageDriver.URLFor(suite.ctx, filename, map[string]interface{}{"method": "HEAD"})
|
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
|
return
|
||||||
}
|
}
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
Loading…
Reference in a new issue