Add a generic error type to capture non-typed errors

Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
This commit is contained in:
Richard Scothern 2015-11-02 13:23:53 -08:00
parent 9637cb40cd
commit bc6e4cdceb
10 changed files with 44 additions and 29 deletions

View file

@ -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 {

View file

@ -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()
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 storageError
return actualErr
} }
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. // GetContent wraps GetContent of underlying storage driver.

View file

@ -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.

View file

@ -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{}
} }
} }

View file

@ -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{}
} }

View file

@ -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{}
} }
} }

View file

@ -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

View file

@ -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{}
} }
} }

View file

@ -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)
}

View file

@ -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)