1
0
mirror of https://github.com/minio/mc.git synced 2025-11-13 12:22:45 +03:00

mc client interface now provides typed errors

This commit is contained in:
Harshavardhana
2015-04-08 22:21:01 -07:00
parent d21d925bd4
commit 6e9fe6dc56
11 changed files with 110 additions and 75 deletions

View File

@@ -54,9 +54,7 @@ var _config *mcConfig
func getMcConfigDir() string {
u, err := user.Current()
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
msg := fmt.Sprintf("Unable to obtain user's home directory. \nError: %s", err)
fatal(msg)
}
@@ -179,6 +177,7 @@ func saveConfig(ctx *cli.Context) error {
// Reload and cache new config
_, err = getMcConfig()
err = iodine.ToError(err)
if os.IsNotExist(err) {
return iodine.New(err, nil)
}
@@ -197,16 +196,12 @@ func getBashCompletion() {
fl, err := os.OpenFile(f, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
defer fl.Close()
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
_, err = fl.Write(b.Bytes())
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
msg := "\nConfiguration written to " + f
@@ -314,17 +309,13 @@ func doConfigCmd(ctx *cli.Context) {
default:
err := saveConfig(ctx)
if os.IsExist(err) {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
msg := fmt.Sprintf("mc: Please rename your current configuration file [%s]\n", getMcConfigFilename())
fatal(msg)
}
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
msg := fmt.Sprintf("mc: Unable to generate config file [%s]. \nError: %v\n", getMcConfigFilename(), err)
fatal(msg)
}

View File

@@ -117,9 +117,7 @@ func multiCopy(targetURLs []string, sourceURL string) (err error) {
for msg := range doPutMultiTarget(targetURLs, md5Hex, sourceSize, targetReaders) {
if msg.err != nil {
if globalDebugFlag {
log.Debug.Println(msg.err)
}
log.Debug.Println(msg.err)
fatal(msg.err)
}
info("Done")
@@ -135,9 +133,7 @@ func doCopyCmd(ctx *cli.Context) {
// Convert arguments to URLs: expand alias, fix format...
urlList, err := parseURLs(ctx)
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
return
}
@@ -146,9 +142,7 @@ func doCopyCmd(ctx *cli.Context) {
err = multiCopy(targetURLs, sourceURL)
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
return
}

View File

@@ -61,43 +61,33 @@ func doListCmd(ctx *cli.Context) {
urlStr, err := parseURL(ctx.Args().First())
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
bucketName, objectName, err := url2Object(urlStr)
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
client, err := getNewClient(globalDebugFlag, urlStr)
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
if bucketName == "" { // List all buckets
buckets, err := client.ListBuckets()
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
printBuckets(buckets)
} else {
items, err = client.ListObjects(bucketName, objectName)
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
printObjects(items)

View File

@@ -27,40 +27,30 @@ import (
func doMakeBucketCmd(ctx *cli.Context) {
urlStr, err := parseURL(ctx.Args().First())
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
bucket, err := url2Bucket(urlStr)
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
clnt, err := getNewClient(globalDebugFlag, urlStr)
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
if !s3.IsValidBucketName(bucket) {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(errInvalidbucket)
}
err = clnt.PutBucket(bucket)
if err != nil {
if globalDebugFlag {
log.Debug.Println(iodine.New(err, nil))
}
log.Debug.Println(iodine.New(err, nil))
fatal(err)
}
}

View File

@@ -17,6 +17,7 @@
package client
import (
"fmt"
"io"
"time"
)
@@ -53,3 +54,72 @@ type Item struct {
type Prefix struct {
Prefix string
}
/// Collection of standard errors
// InvalidBucketName - bucket name invalid
type InvalidBucketName struct {
Bucket string
}
func (e InvalidBucketName) Error() string {
return fmt.Sprintf("Invalid bucketname %v", e.Bucket)
}
// InvalidArgument - bad arguments provided
type InvalidArgument struct{}
func (e InvalidArgument) Error() string {
return fmt.Sprint("invalid arguments")
}
// InvalidMaxKeys - invalid maxkeys provided
type InvalidMaxKeys struct {
Maxkeys int
}
func (e InvalidMaxKeys) Error() string {
return fmt.Sprintf("invalid maxkeys %v", e.Maxkeys)
}
// InvalidAuthorizationKey - invalid authorization key
type InvalidAuthorizationKey struct{}
func (e InvalidAuthorizationKey) Error() string {
return fmt.Sprint("invalid authorization key")
}
// AuthorizationKeyEmpty - empty auth key provided
type AuthorizationKeyEmpty struct{}
func (e AuthorizationKeyEmpty) Error() string {
return fmt.Sprint("authorization key empty")
}
// InvalidRange - invalid range requested
type InvalidRange struct {
Offset int64
}
func (e InvalidRange) Error() string {
return fmt.Sprintf("invalid range value %v", e.Offset)
}
// BucketNotFound - bucket requested does not exist
type BucketNotFound struct {
Bucket string
}
func (e BucketNotFound) Error() string {
return fmt.Sprintf("bucket: %v not found", e.Bucket)
}
// ObjectNotFound - object requested does not exist
type ObjectNotFound struct {
Bucket string
Object string
}
func (e ObjectNotFound) Error() string {
return fmt.Sprintf("object %v not found at bucket: %v", e.Bucket, e.Object)
}

View File

@@ -39,9 +39,7 @@ limitations under the License.
package s3
import (
"errors"
"fmt"
"os"
"strings"
"net/http"
@@ -81,7 +79,7 @@ func (c *s3Client) ListBuckets() ([]*client.Bucket, error) {
// PutBucket - create new bucket
func (c *s3Client) PutBucket(bucket string) error {
if !IsValidBucketName(bucket) || strings.Contains(bucket, ".") {
return errors.New("invalid bucket")
return iodine.New(client.InvalidBucketName{Bucket: bucket}, nil)
}
u := fmt.Sprintf("%s://%s/%s", c.Scheme, c.Host, bucket)
req := newReq(u)
@@ -102,10 +100,10 @@ func (c *s3Client) PutBucket(bucket string) error {
func (c *s3Client) StatBucket(bucket string) error {
if bucket == "" {
return iodine.New(errors.New("invalid argument"), nil)
return iodine.New(client.InvalidArgument{}, nil)
}
if !IsValidBucketName(bucket) || strings.Contains(bucket, ".") {
return errors.New("invalid bucket")
return iodine.New(client.InvalidBucketName{Bucket: bucket}, nil)
}
u := fmt.Sprintf("%s://%s/%s", c.Scheme, c.Host, bucket)
req := newReq(u)
@@ -119,7 +117,7 @@ func (c *s3Client) StatBucket(bucket string) error {
switch res.StatusCode {
case http.StatusNotFound:
return iodine.New(os.ErrNotExist, nil)
return iodine.New(client.BucketNotFound{Bucket: bucket}, nil)
case http.StatusOK:
return nil
default:

View File

@@ -79,7 +79,7 @@ func (c *s3Client) queryObjects(bucket string, startAt, prefix, delimiter string
var buffer bytes.Buffer
if maxKeys <= 0 {
return nil, nil, iodine.New(errors.New("negative maxKeys are invalid"), nil)
return nil, nil, iodine.New(client.InvalidMaxKeys{Maxkeys: maxKeys}, nil)
}
marker := startAt

View File

@@ -51,6 +51,7 @@ import (
"encoding/xml"
"github.com/minio-io/mc/pkg/client"
"github.com/minio-io/minio/pkg/iodine"
)
type listBucketResults struct {
@@ -164,7 +165,7 @@ func listAllMyBuckets(r io.Reader) ([]*client.Bucket, error) {
}
var res allMyBuckets
if err := xml.NewDecoder(r).Decode(&res); err != nil {
return nil, err
return nil, iodine.New(err, nil)
}
return res.Buckets.Bucket, nil
}

View File

@@ -17,8 +17,10 @@
package s3
import (
"errors"
"net/http"
"github.com/minio-io/mc/pkg/client"
"github.com/minio-io/minio/pkg/iodine"
)
// HTTPTracer provides callback hook mechanism for HTTP transport.
@@ -38,24 +40,24 @@ func (t RoundTripTrace) RoundTrip(req *http.Request) (res *http.Response, err er
if t.Trace != nil {
err = t.Trace.Request(req)
if err != nil {
return nil, err
return nil, iodine.New(err, nil)
}
}
if t.Transport == nil {
return nil, errors.New("TraceRoundTrip.Transport is nil")
return nil, iodine.New(client.InvalidArgument{}, nil)
}
res, err = t.Transport.RoundTrip(req)
if err != nil {
return res, err
return res, iodine.New(err, nil)
}
if t.Trace != nil {
t.Trace.Response(res)
}
return res, err
return res, iodine.New(err, nil)
}
// GetNewTraceTransport returns a traceable transport

View File

@@ -39,10 +39,8 @@ limitations under the License.
package s3
import (
"errors"
"fmt"
"io"
"os"
"strconv"
"strings"
"time"
@@ -52,6 +50,7 @@ import (
"io/ioutil"
"net/http"
"github.com/minio-io/mc/pkg/client"
"github.com/minio-io/minio/pkg/iodine"
)
@@ -86,7 +85,7 @@ func (c *s3Client) Put(bucket, key, md5HexString string, size int64, contents io
// Stat - returns 0, "", os.ErrNotExist if not on S3
func (c *s3Client) StatObject(bucket, key string) (size int64, date time.Time, reterr error) {
if bucket == "" || key == "" {
return 0, date, iodine.New(os.ErrNotExist, nil)
return 0, date, iodine.New(client.InvalidArgument{}, nil)
}
req := newReq(c.keyURL(bucket, key))
req.Method = "HEAD"
@@ -99,7 +98,7 @@ func (c *s3Client) StatObject(bucket, key string) (size int64, date time.Time, r
switch res.StatusCode {
case http.StatusNotFound:
return 0, date, iodine.New(os.ErrNotExist, nil)
return 0, date, iodine.New(client.ObjectNotFound{Bucket: bucket, Object: key}, nil)
case http.StatusOK:
size, err = strconv.ParseInt(res.Header.Get("Content-Length"), 10, 64)
if err != nil {
@@ -139,7 +138,7 @@ func (c *s3Client) Get(bucket, key string) (body io.ReadCloser, size int64, md5
// If length is negative, the rest of the object is returned.
func (c *s3Client) GetPartial(bucket, key string, offset, length int64) (body io.ReadCloser, size int64, md5 string, err error) {
if offset < 0 {
return nil, 0, "", iodine.New(errors.New("invalid negative offset"), nil)
return nil, 0, "", iodine.New(client.InvalidRange{Offset: offset}, nil)
}
req := newReq(c.keyURL(bucket, key))
if length >= 0 {

View File

@@ -17,10 +17,10 @@
package s3
import (
"errors"
"net/http"
"strings"
"github.com/minio-io/mc/pkg/client"
"github.com/minio-io/minio/pkg/iodine"
)
@@ -56,10 +56,10 @@ Example AWS S3 Request / Response
// HTTP S3 request validator.
func (t s3Verify) Request(req *http.Request) error {
if req.Header.Get("Authorization") == "" {
return iodine.New(errors.New("Client request header has authorization key"), nil)
return iodine.New(client.AuthorizationKeyEmpty{}, nil)
}
if !strings.HasPrefix(req.Header.Get("Authorization"), "AWS") {
return iodine.New(errors.New("Client request header has malformed authorization key"), nil)
return iodine.New(client.InvalidAuthorizationKey{}, nil)
}
return nil
}