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:
@@ -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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
fatal(err)
|
||||
}
|
||||
_, err = fl.Write(b.Bytes())
|
||||
if err != nil {
|
||||
if globalDebugFlag {
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
msg := fmt.Sprintf("mc: Unable to generate config file [%s]. \nError: %v\n", getMcConfigFilename(), err)
|
||||
fatal(msg)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
10
cmd-ls.go
10
cmd-ls.go
@@ -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))
|
||||
}
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
bucketName, objectName, err := url2Object(urlStr)
|
||||
if err != nil {
|
||||
if globalDebugFlag {
|
||||
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))
|
||||
}
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
if bucketName == "" { // List all buckets
|
||||
buckets, err := client.ListBuckets()
|
||||
if err != nil {
|
||||
if globalDebugFlag {
|
||||
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))
|
||||
}
|
||||
fatal(err)
|
||||
}
|
||||
printObjects(items)
|
||||
|
||||
10
cmd-mb.go
10
cmd-mb.go
@@ -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))
|
||||
}
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
bucket, err := url2Bucket(urlStr)
|
||||
if err != nil {
|
||||
if globalDebugFlag {
|
||||
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))
|
||||
}
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
if !s3.IsValidBucketName(bucket) {
|
||||
if globalDebugFlag {
|
||||
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))
|
||||
}
|
||||
fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user