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

Convert all errors.New and fmt.Errorf to typed errors

This commit is contained in:
Harshavardhana
2015-06-13 21:36:42 -07:00
parent 4b99854f4d
commit c04acf4d50
19 changed files with 104 additions and 70 deletions

View File

@@ -49,7 +49,7 @@ func isValidAliasName(aliasName string) bool {
func aliasExpand(aliasedURL string, aliases map[string]string) (newURL string, err error) { func aliasExpand(aliasedURL string, aliases map[string]string) (newURL string, err error) {
u, err := client.Parse(aliasedURL) u, err := client.Parse(aliasedURL)
if err != nil { if err != nil {
return aliasedURL, iodine.New(errInvalidURL{url: aliasedURL}, nil) return aliasedURL, iodine.New(errInvalidURL{URL: aliasedURL}, nil)
} }
// proper URL // proper URL
if u.Host != "" { if u.Host != "" {
@@ -69,7 +69,7 @@ func aliasExpand(aliasedURL string, aliases map[string]string) (newURL string, e
trimmedURL := expandedURL + "/" + strings.TrimPrefix(strings.TrimPrefix(splits[1], "/"), "\\") trimmedURL := expandedURL + "/" + strings.TrimPrefix(strings.TrimPrefix(splits[1], "/"), "\\")
u, err := client.Parse(trimmedURL) u, err := client.Parse(trimmedURL)
if err != nil { if err != nil {
return aliasedURL, iodine.New(errInvalidURL{url: aliasedURL}, nil) return aliasedURL, iodine.New(errInvalidURL{URL: aliasedURL}, nil)
} }
return u.String(), nil return u.String(), nil
} }

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"github.com/minio/cli" "github.com/minio/cli"
@@ -68,7 +67,7 @@ func runAccessCmd(ctx *cli.Context) {
if !isMcConfigExist() { if !isMcConfigExist() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Please run \"mc config generate\"", Message: "Please run \"mc config generate\"",
Error: iodine.New(errors.New("\"mc\" is not configured"), nil), Error: iodine.New(errNotConfigured{}, nil),
}) })
} }
config, err := getMcConfig() config, err := getMcConfig()
@@ -89,7 +88,7 @@ func runAccessCmd(ctx *cli.Context) {
if !acl.isValidBucketACL() { if !acl.isValidBucketACL() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Valid types are [private, public, readonly].", Message: "Valid types are [private, public, readonly].",
Error: iodine.New(errors.New("Invalid ACL Type "+acl.String()+""), nil), Error: iodine.New(errInvalidACL{acl: acl.String()}, nil),
}) })
} }
targetURLs = targetURLs[1:] // 1 or more target URLs targetURLs = targetURLs[1:] // 1 or more target URLs

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
@@ -69,7 +68,7 @@ func runCatCmd(ctx *cli.Context) {
if !isMcConfigExist() { if !isMcConfigExist() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Please run \"mc config generate\"", Message: "Please run \"mc config generate\"",
Error: iodine.New(errors.New("\"mc\" is not configured"), nil), Error: iodine.New(errNotConfigured{}, nil),
}) })
} }
config, err := getMcConfig() config, err := getMcConfig()
@@ -118,9 +117,9 @@ func doCatCmd(sourceURLs []string) (string, error) {
// stdout closed by the user. Gracefully exit. // stdout closed by the user. Gracefully exit.
return "", nil return "", nil
} }
return "Writing data to stdout failed, unexpected problem.. please report this error", iodine.New(e, nil) return "Writing data to stdout failed, unexpected problem.. please report this error", iodine.New(err, nil)
default: default:
return "Reading data from source failed: " + url, iodine.New(errors.New("Copy data from source failed"), nil) return "Reading data from source failed: " + url, iodine.New(err, nil)
} }
} }
} }

View File

@@ -154,7 +154,7 @@ func addAlias(aliases []string) (quick.Config, error) {
return nil, iodine.New(errInvalidAliasName{name: aliasName}, nil) return nil, iodine.New(errInvalidAliasName{name: aliasName}, nil)
} }
if !strings.HasPrefix(url, "http") { if !strings.HasPrefix(url, "http") {
return nil, iodine.New(errInvalidURL{url: url}, nil) return nil, iodine.New(errInvalidURL{URL: url}, nil)
} }
if !isValidAliasName(aliasName) { if !isValidAliasName(aliasName) {
return nil, iodine.New(errInvalidAliasName{name: aliasName}, nil) return nil, iodine.New(errInvalidAliasName{name: aliasName}, nil)

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"math" "math"
@@ -185,7 +184,7 @@ func runCopyCmd(ctx *cli.Context) {
if !isMcConfigExist() { if !isMcConfigExist() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Please run \"mc config generate\"", Message: "Please run \"mc config generate\"",
Error: iodine.New(errors.New("\"mc\" is not configured"), nil), Error: iodine.New(errNotConfigured{}, nil),
}) })
} }

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"github.com/minio/cli" "github.com/minio/cli"
@@ -62,7 +61,7 @@ func runDiffCmd(ctx *cli.Context) {
if !isMcConfigExist() { if !isMcConfigExist() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Please run \"mc config generate\"", Message: "Please run \"mc config generate\"",
Error: iodine.New(errors.New("\"mc\" is not configured"), nil), Error: iodine.New(errNotConfigured{}, nil),
}) })
} }
config, err := getMcConfig() config, err := getMcConfig()

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"github.com/minio/cli" "github.com/minio/cli"
@@ -87,7 +86,7 @@ func runListCmd(ctx *cli.Context) {
if !isMcConfigExist() { if !isMcConfigExist() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Please run \"mc config generate\"", Message: "Please run \"mc config generate\"",
Error: iodine.New(errors.New("\"mc\" is not configured"), nil), Error: iodine.New(errNotConfigured{}, nil),
}) })
} }
config, err := getMcConfig() config, err := getMcConfig()

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"github.com/minio/cli" "github.com/minio/cli"
@@ -64,14 +63,14 @@ func runMakeBucketCmd(ctx *cli.Context) {
if !isMcConfigExist() { if !isMcConfigExist() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Please run \"mc config generate\"", Message: "Please run \"mc config generate\"",
Error: errors.New("\"mc\" is not configured"), Error: iodine.New(errNotConfigured{}, nil),
}) })
} }
config, err := getMcConfig() config, err := getMcConfig()
if err != nil { if err != nil {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Unable to read config file " + mustGetMcConfigPath() + "", Message: "Unable to read config file " + mustGetMcConfigPath() + "",
Error: err, Error: iodine.New(err, nil),
}) })
} }
for _, arg := range ctx.Args() { for _, arg := range ctx.Args() {
@@ -81,12 +80,12 @@ func runMakeBucketCmd(ctx *cli.Context) {
case errUnsupportedScheme: case errUnsupportedScheme:
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: fmt.Sprintf("Unknown type of URL %s", e.url), Message: fmt.Sprintf("Unknown type of URL %s", e.url),
Error: e, Error: iodine.New(e, nil),
}) })
default: default:
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: fmt.Sprintf("Unable to parse argument %s", arg), Message: fmt.Sprintf("Unable to parse argument %s", arg),
Error: err, Error: iodine.New(err, nil),
}) })
} }
} }
@@ -94,7 +93,7 @@ func runMakeBucketCmd(ctx *cli.Context) {
if err != nil { if err != nil {
console.Errors(ErrorMessage{ console.Errors(ErrorMessage{
Message: errorMsg, Message: errorMsg,
Error: err, Error: iodine.New(err, nil),
}) })
} }
} }

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"math" "math"
@@ -165,7 +164,7 @@ func runSyncCmd(ctx *cli.Context) {
if !isMcConfigExist() { if !isMcConfigExist() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Please run \"mc config generate\"", Message: "Please run \"mc config generate\"",
Error: iodine.New(errors.New("\"mc\" is not configured"), nil), Error: iodine.New(errNotConfigured{}, nil),
}) })
} }

View File

@@ -18,7 +18,6 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors"
"net/http" "net/http"
"runtime" "runtime"
"time" "time"
@@ -104,7 +103,7 @@ func runUpdateCmd(ctx *cli.Context) {
if !isMcConfigExist() { if !isMcConfigExist() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Please run \"mc config generate\"", Message: "Please run \"mc config generate\"",
Error: iodine.New(errors.New("\"mc\" is not configured"), nil), Error: iodine.New(errNotConfigured{}, nil),
}) })
} }
msg, err := doUpdateCheck() msg, err := doUpdateCheck()

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"io" "io"
"os" "os"
"runtime" "runtime"
@@ -105,7 +104,7 @@ func putTargets(targetURLs []string, length int64, reader io.Reader) <-chan erro
func getNewClient(urlStr string, auth *hostConfig) (clnt client.Client, err error) { func getNewClient(urlStr string, auth *hostConfig) (clnt client.Client, err error) {
url, err := client.Parse(urlStr) url, err := client.Parse(urlStr)
if err != nil { if err != nil {
return nil, iodine.New(errInvalidURL{url: urlStr}, nil) return nil, iodine.New(errInvalidURL{URL: urlStr}, nil)
} }
switch url.Type { switch url.Type {
case client.Object: // Minio and S3 compatible object storage case client.Object: // Minio and S3 compatible object storage
@@ -134,7 +133,7 @@ func getNewClient(urlStr string, auth *hostConfig) (clnt client.Client, err erro
case client.Filesystem: case client.Filesystem:
return fs.New(urlStr) return fs.New(urlStr)
} }
return nil, iodine.New(errInvalidURL{url: urlStr}, nil) return nil, iodine.New(errInvalidURL{URL: urlStr}, nil)
} }
// url2Stat - Returns client, config and its stat Content from the URL // url2Stat - Returns client, config and its stat Content from the URL
@@ -165,7 +164,7 @@ func url2Client(url string) (client.Client, error) {
} }
if urlParse.Path == "" { if urlParse.Path == "" {
return nil, iodine.New(errors.New("invalid path"), nil) return nil, iodine.New(errInvalidURL{URL: url}, nil)
} }
urlonfig, err := getHostConfig(url) urlonfig, err := getHostConfig(url)
@@ -177,6 +176,7 @@ func url2Client(url string) (client.Client, error) {
if err != nil { if err != nil {
return nil, iodine.New(err, nil) return nil, iodine.New(err, nil)
} }
return client, nil return client, nil
} }

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"fmt"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -191,7 +190,7 @@ func prepareCopyURLsTypeB(sourceURL string, targetURL string) <-chan cpURLs {
if err == nil { if err == nil {
if !targetContent.Type.IsDir() { if !targetContent.Type.IsDir() {
// Target exists, but is not a directory. // Target exists, but is not a directory.
cpURLsCh <- cpURLs{Error: iodine.New(fmt.Errorf("Target [%s] is not a directory.", targetURL), nil)} cpURLsCh <- cpURLs{Error: iodine.New(errTargetIsNotDir{URL: targetURL}, nil)}
return return
} }
} // Else name is available to create. } // Else name is available to create.
@@ -225,7 +224,7 @@ func prepareCopyURLsTypeC(sourceURL, targetURL string) <-chan cpURLs {
defer close(cpURLsCh) defer close(cpURLsCh)
if !isURLRecursive(sourceURL) { if !isURLRecursive(sourceURL) {
// Source is not of recursive type. // Source is not of recursive type.
cpURLsCh <- cpURLs{Error: iodine.New(fmt.Errorf("Source [%s] is not recursive.", sourceURL), nil)} cpURLsCh <- cpURLs{Error: iodine.New(errSourceNotRecursive{URL: sourceURL}, nil)}
return return
} }
@@ -247,7 +246,7 @@ func prepareCopyURLsTypeC(sourceURL, targetURL string) <-chan cpURLs {
if !sourceContent.Type.IsDir() { if !sourceContent.Type.IsDir() {
// Source is not a dir. // Source is not a dir.
cpURLsCh <- cpURLs{Error: iodine.New(fmt.Errorf("Source [%s] is not a directory.", sourceURL), nil)} cpURLsCh <- cpURLs{Error: iodine.New(errSourceIsNotDir{URL: sourceURL}, nil)}
return return
} }
@@ -261,13 +260,13 @@ func prepareCopyURLsTypeC(sourceURL, targetURL string) <-chan cpURLs {
targetContent, err := targetClient.Stat() targetContent, err := targetClient.Stat()
if err != nil { if err != nil {
// Target does not exist. // Target does not exist.
cpURLsCh <- cpURLs{Error: iodine.New(fmt.Errorf("Target directory [%s] does not exist.", targetURL), nil)} cpURLsCh <- cpURLs{Error: iodine.New(errTargetNotFound{URL: targetURL}, nil)}
return return
} }
if !targetContent.Type.IsDir() { if !targetContent.Type.IsDir() {
// Target exists, but is not a directory. // Target exists, but is not a directory.
cpURLsCh <- cpURLs{Error: iodine.New(fmt.Errorf("Target [%s] is not a directory.", targetURL), nil)} cpURLsCh <- cpURLs{Error: iodine.New(errTargetIsNotDir{URL: targetURL}, nil)}
return return
} }
@@ -333,17 +332,17 @@ func prepareCopyURLsTypeD(sourceURLs []string, targetURL string) <-chan cpURLs {
targetContent, err := targetClient.Stat() targetContent, err := targetClient.Stat()
if err != nil { if err != nil {
// Target does not exist. // Target does not exist.
cpURLsCh <- cpURLs{Error: iodine.New(fmt.Errorf("Target directory [%s] does not exist.", targetURL), nil)} cpURLsCh <- cpURLs{Error: iodine.New(errTargetNotFound{URL: targetURL}, nil)}
return return
} }
if !targetContent.Type.IsDir() { if !targetContent.Type.IsDir() {
// Target exists, but is not a directory. // Target exists, but is not a directory.
cpURLsCh <- cpURLs{Error: iodine.New(fmt.Errorf("Target [%s] is not a directory.", targetURL), nil)} cpURLsCh <- cpURLs{Error: iodine.New(errTargetIsNotDir{URL: targetURL}, nil)}
return return
} }
if sourceURLs == nil { if sourceURLs == nil {
// Source list is empty. // Source list is empty.
cpURLsCh <- cpURLs{Error: iodine.New(fmt.Errorf("Source list is empty"), nil)} cpURLsCh <- cpURLs{Error: iodine.New(errSourceListEmpty{}, nil)}
return return
} }
for _, sourceURL := range sourceURLs { for _, sourceURL := range sourceURLs {

View File

@@ -16,6 +16,20 @@
package main package main
type errInvalidACL struct {
acl string
}
func (e errInvalidACL) Error() string {
return "Invalid ACL Type " + e.acl + "."
}
type errNotConfigured struct{}
func (e errNotConfigured) Error() string {
return "mc not configured."
}
type errNotAnObject struct { type errNotAnObject struct {
url string url string
} }
@@ -39,14 +53,6 @@ func (e errUnsupportedScheme) Error() string {
return "Unsuppported URL scheme: " + e.scheme return "Unsuppported URL scheme: " + e.scheme
} }
type errInvalidURL struct {
url string
}
func (e errInvalidURL) Error() string {
return "Invalid URL: " + e.url
}
type errInvalidGlobURL struct { type errInvalidGlobURL struct {
glob string glob string
request string request string
@@ -79,7 +85,7 @@ func (e errNoMatchingHost) Error() string {
type errConfigExists struct{} type errConfigExists struct{}
func (e errConfigExists) Error() string { func (e errConfigExists) Error() string {
return "Config exists" return "Config exists."
} }
// errAliasExists - alias exists // errAliasExists - alias exists
@@ -88,20 +94,24 @@ type errAliasExists struct {
} }
func (e errAliasExists) Error() string { func (e errAliasExists) Error() string {
return "Alias name: " + e.name + " exists" return "Alias name: " + e.name + " exists."
} }
type errInvalidSource struct { type errInvalidURL struct {
URL string URL string
} }
func (e errInvalidURL) Error() string {
return "Invalid url " + e.URL
}
type errInvalidSource errInvalidURL
func (e errInvalidSource) Error() string { func (e errInvalidSource) Error() string {
return "Invalid source " + e.URL return "Invalid source " + e.URL
} }
type errInvalidTarget struct { type errInvalidTarget errInvalidURL
URL string
}
func (e errInvalidTarget) Error() string { func (e errInvalidTarget) Error() string {
return "Invalid target " + e.URL return "Invalid target " + e.URL
@@ -114,3 +124,33 @@ type errInvalidTheme struct {
func (e errInvalidTheme) Error() string { func (e errInvalidTheme) Error() string {
return "Theme " + e.Theme + " is not supported." return "Theme " + e.Theme + " is not supported."
} }
type errTargetIsNotDir errInvalidURL
func (e errTargetIsNotDir) Error() string {
return "Target " + e.URL + " is not a directory."
}
type errTargetNotFound errInvalidURL
func (e errTargetNotFound) Error() string {
return "Target directory " + e.URL + " does not exist."
}
type errSourceNotRecursive errInvalidURL
func (e errSourceNotRecursive) Error() string {
return "Source " + e.URL + " is not recursive."
}
type errSourceIsNotDir errTargetIsNotDir
func (e errSourceIsNotDir) Error() string {
return "Source " + e.URL + " is not a directory."
}
type errSourceListEmpty errInvalidArgument
func (e errSourceListEmpty) Error() string {
return "Source list is empty."
}

View File

@@ -37,7 +37,7 @@ func getHostConfig(URL string) (*hostConfig, error) {
} }
url, err := client.Parse(URL) url, err := client.Parse(URL)
if err != nil { if err != nil {
return nil, iodine.New(errInvalidURL{url: URL}, nil) return nil, iodine.New(errInvalidURL{URL: URL}, nil)
} }
// No host matching or keys needed for filesystem requests // No host matching or keys needed for filesystem requests
if url.Type == client.Filesystem { if url.Type == client.Filesystem {

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"os/user" "os/user"
@@ -145,7 +144,7 @@ func main() {
if !isMcConfigExist() { if !isMcConfigExist() {
console.Fatals(ErrorMessage{ console.Fatals(ErrorMessage{
Message: "Please run \"mc config generate\"", Message: "Please run \"mc config generate\"",
Error: iodine.New(errors.New("\"mc\" is not configured"), nil), Error: iodine.New(errNotConfigured{}, nil),
}) })
} }
return nil return nil

View File

@@ -30,22 +30,20 @@ func (e APINotImplemented) Error() string {
} }
// GenericError - generic error // GenericError - generic error
type GenericError struct { type GenericError struct{}
Err error
}
// UnexpectedError - unexpected error // UnexpectedError - unexpected error
type UnexpectedError GenericError type UnexpectedError GenericError
func (e UnexpectedError) Error() string { func (e UnexpectedError) Error() string {
return e.Err.Error() + ", please report this error" return "Unexpected error, please report this error at https://github.com/minio/mc/issues"
} }
// InvalidArgument - bad arguments provided // InvalidArgument - bad arguments provided
type InvalidArgument GenericError type InvalidArgument GenericError
func (e InvalidArgument) Error() string { func (e InvalidArgument) Error() string {
return e.Err.Error() return "Invalid argument"
} }
// InvalidRange - invalid range requested // InvalidRange - invalid range requested
@@ -56,3 +54,12 @@ type InvalidRange struct {
func (e InvalidRange) Error() string { func (e InvalidRange) Error() string {
return "invalid range offset: " + strconv.FormatInt(e.Offset, 10) return "invalid range offset: " + strconv.FormatInt(e.Offset, 10)
} }
// InvalidACLType - invalid acl type
type InvalidACLType struct {
ACL string
}
func (e InvalidACLType) Error() string {
return "invalid acl type: " + e.ACL
}

View File

@@ -17,7 +17,6 @@
package fs package fs
import ( import (
"errors"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
@@ -376,7 +375,7 @@ func (f *fsClient) MakeBucket() error {
// SetBucketACL - create a new bucket // SetBucketACL - create a new bucket
func (f *fsClient) SetBucketACL(acl string) error { func (f *fsClient) SetBucketACL(acl string) error {
if !isValidBucketACL(acl) { if !isValidBucketACL(acl) {
return iodine.New(errors.New("invalid acl"), nil) return iodine.New(client.InvalidACLType{ACL: acl}, nil)
} }
err := os.MkdirAll(f.path, aclToPerm(acl)) err := os.MkdirAll(f.path, aclToPerm(acl))
if err != nil { if err != nil {

View File

@@ -17,7 +17,6 @@
package s3 package s3
import ( import (
"errors"
"net/http" "net/http"
"time" "time"
@@ -43,7 +42,7 @@ func (t RoundTripTrace) RoundTrip(req *http.Request) (res *http.Response, err er
timeStamp := time.Now() timeStamp := time.Now()
if t.Transport == nil { if t.Transport == nil {
return nil, iodine.New(client.InvalidArgument{Err: errors.New("invalid argument")}, nil) return nil, iodine.New(client.InvalidArgument{}, nil)
} }
res, err = t.Transport.RoundTrip(req) res, err = t.Transport.RoundTrip(req)

View File

@@ -17,7 +17,6 @@
package main package main
import ( import (
"fmt"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -123,7 +122,7 @@ func prepareSyncURLsTypeC(sourceURL string, targetURLs []string) <-chan syncURLs
defer close(syncURLsCh) defer close(syncURLsCh)
if !isURLRecursive(sourceURL) { if !isURLRecursive(sourceURL) {
// Source is not of recursive type. // Source is not of recursive type.
syncURLsCh <- syncURLs{Error: iodine.New(fmt.Errorf("Source [%s] is not recursive.", sourceURL), nil)} syncURLsCh <- syncURLs{Error: iodine.New(errSourceNotRecursive{URL: sourceURL}, nil)}
return return
} }
// add `/` after trimming off `...` to emulate directories // add `/` after trimming off `...` to emulate directories
@@ -143,7 +142,7 @@ func prepareSyncURLsTypeC(sourceURL string, targetURLs []string) <-chan syncURLs
if !sourceContent.Type.IsDir() { if !sourceContent.Type.IsDir() {
// Source is not a dir. // Source is not a dir.
syncURLsCh <- syncURLs{Error: iodine.New(fmt.Errorf("Source [%s] is not a directory.", sourceURL), nil)} syncURLsCh <- syncURLs{Error: iodine.New(errSourceIsNotDir{URL: sourceURL}, nil)}
return return
} }
@@ -158,13 +157,13 @@ func prepareSyncURLsTypeC(sourceURL string, targetURLs []string) <-chan syncURLs
targetContent, err := targetClient.Stat() targetContent, err := targetClient.Stat()
if err != nil { if err != nil {
// Target does not exist. // Target does not exist.
syncURLsCh <- syncURLs{Error: iodine.New(fmt.Errorf("Target directory [%s] does not exist.", targetURL), nil)} syncURLsCh <- syncURLs{Error: iodine.New(errTargetNotFound{URL: targetURL}, nil)}
return return
} }
if !targetContent.Type.IsDir() { if !targetContent.Type.IsDir() {
// Target exists, but is not a directory. // Target exists, but is not a directory.
syncURLsCh <- syncURLs{Error: iodine.New(fmt.Errorf("Target [%s] is not a directory.", targetURL), nil)} syncURLsCh <- syncURLs{Error: iodine.New(errTargetIsNotDir{URL: targetURL}, nil)}
return return
} }
} }