Use standard error messages
This commit is contained in:
parent
9c697a99f5
commit
39521e331d
15 changed files with 87 additions and 105 deletions
|
@ -32,8 +32,7 @@ func BucketViewHandler(s3 S3Client) http.Handler {
|
|||
|
||||
t, err := template.ParseFiles(l, p)
|
||||
if err != nil {
|
||||
msg := "error parsing templates"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -42,14 +41,12 @@ func BucketViewHandler(s3 S3Client) http.Handler {
|
|||
objectCh := s3.ListObjectsV2(bucketName, "", true, doneCh)
|
||||
for object := range objectCh {
|
||||
if object.Err != nil {
|
||||
msg := "error listing objects"
|
||||
code := http.StatusInternalServerError
|
||||
if object.Err.Error() == "The specified bucket does not exist." {
|
||||
msg = "bucket not found"
|
||||
if object.Err.Error() == ErrBucketDoesNotExist {
|
||||
code = http.StatusNotFound
|
||||
}
|
||||
|
||||
handleHTTPError(w, msg, object.Err, code)
|
||||
handleHTTPError(w, code, object.Err)
|
||||
return
|
||||
}
|
||||
objectWithIcon := ObjectWithIcon{object, icon(object.Key)}
|
||||
|
@ -63,8 +60,7 @@ func BucketViewHandler(s3 S3Client) http.Handler {
|
|||
|
||||
err = t.ExecuteTemplate(w, "layout", bucketPage)
|
||||
if err != nil {
|
||||
msg := "error executing template"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
|
@ -88,7 +88,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
s3: &S3ClientMock{},
|
||||
bucketName: "testBucket",
|
||||
expectedStatusCode: http.StatusNotFound,
|
||||
expectedBodyCountains: "bucket not found\n",
|
||||
expectedBodyCountains: http.StatusText(http.StatusNotFound),
|
||||
},
|
||||
"s3 error": {
|
||||
s3: &S3ClientMock{
|
||||
|
@ -96,7 +96,7 @@ func TestBucketViewHandler(t *testing.T) {
|
|||
},
|
||||
bucketName: "testBucket",
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBodyCountains: "error listing objects\n",
|
||||
expectedBodyCountains: http.StatusText(http.StatusInternalServerError),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -14,22 +14,19 @@ func BucketsViewHandler(s3 S3Client) http.Handler {
|
|||
|
||||
t, err := template.ParseFiles(l, p)
|
||||
if err != nil {
|
||||
msg := "error parsing templates"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
buckets, err := s3.ListBuckets()
|
||||
if err != nil {
|
||||
msg := "error listing buckets"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = t.ExecuteTemplate(w, "layout", buckets)
|
||||
if err != nil {
|
||||
msg := "error executing template"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
|
@ -37,7 +37,7 @@ func TestBucketsViewHandler(t *testing.T) {
|
|||
Err: errors.New("mocked S3 error"),
|
||||
},
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBodyContains: "error listing buckets\n",
|
||||
expectedBodyContains: http.StatusText(http.StatusInternalServerError),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -14,15 +14,13 @@ func CreateBucketHandler(s3 S3Client) http.Handler {
|
|||
|
||||
err := json.NewDecoder(r.Body).Decode(&bucket)
|
||||
if err != nil {
|
||||
msg := "error decoding json"
|
||||
handleHTTPError(w, msg, err, http.StatusUnprocessableEntity)
|
||||
handleHTTPError(w, http.StatusUnprocessableEntity, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = s3.MakeBucket(bucket.Name, "")
|
||||
if err != nil {
|
||||
msg := "error making bucket"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -31,8 +29,7 @@ func CreateBucketHandler(s3 S3Client) http.Handler {
|
|||
|
||||
err = json.NewEncoder(w).Encode(bucket)
|
||||
if err != nil {
|
||||
msg := "error encoding json"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
|
@ -14,36 +14,36 @@ func TestCreateBucketHandler(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
|
||||
tests := map[string]struct {
|
||||
s3 S3Client
|
||||
body string
|
||||
expectedStatusCode int
|
||||
expectedBody string
|
||||
s3 S3Client
|
||||
body string
|
||||
expectedStatusCode int
|
||||
expectedBodyContains string
|
||||
}{
|
||||
"success": {
|
||||
s3: &S3ClientMock{},
|
||||
body: "{\"name\":\"myBucket\"}",
|
||||
expectedStatusCode: http.StatusCreated,
|
||||
expectedBody: "{\"name\":\"myBucket\",\"creationDate\":\"0001-01-01T00:00:00Z\"}\n",
|
||||
s3: &S3ClientMock{},
|
||||
body: "{\"name\":\"myBucket\"}",
|
||||
expectedStatusCode: http.StatusCreated,
|
||||
expectedBodyContains: "{\"name\":\"myBucket\",\"creationDate\":\"0001-01-01T00:00:00Z\"}\n",
|
||||
},
|
||||
"empty request": {
|
||||
s3: &S3ClientMock{},
|
||||
body: "",
|
||||
expectedStatusCode: http.StatusUnprocessableEntity,
|
||||
expectedBody: "error decoding json\n",
|
||||
s3: &S3ClientMock{},
|
||||
body: "",
|
||||
expectedStatusCode: http.StatusUnprocessableEntity,
|
||||
expectedBodyContains: http.StatusText(http.StatusUnprocessableEntity),
|
||||
},
|
||||
"malformed request": {
|
||||
s3: &S3ClientMock{},
|
||||
body: "}",
|
||||
expectedStatusCode: http.StatusUnprocessableEntity,
|
||||
expectedBody: "error decoding json\n",
|
||||
s3: &S3ClientMock{},
|
||||
body: "}",
|
||||
expectedStatusCode: http.StatusUnprocessableEntity,
|
||||
expectedBodyContains: http.StatusText(http.StatusUnprocessableEntity),
|
||||
},
|
||||
"s3 error": {
|
||||
s3: &S3ClientMock{
|
||||
Err: errors.New("mocked S3 error"),
|
||||
},
|
||||
body: "{\"name\":\"myBucket\"}",
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBody: "error making bucket\n",
|
||||
body: "{\"name\":\"myBucket\"}",
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBodyContains: http.StatusText(http.StatusInternalServerError),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,6 @@ func TestCreateBucketHandler(t *testing.T) {
|
|||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, rr.Code, tcID)
|
||||
assert.Equal(tc.expectedBody, rr.Body.String(), tcID)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains, tcID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@ func CreateObjectHandler(s3 S3Client) http.Handler {
|
|||
|
||||
err := json.NewDecoder(r.Body).Decode(©)
|
||||
if err != nil {
|
||||
msg := "error decoding json"
|
||||
handleHTTPError(w, msg, err, http.StatusUnprocessableEntity)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -37,8 +36,7 @@ func CreateObjectHandler(s3 S3Client) http.Handler {
|
|||
objectSource := fmt.Sprintf("/%s/%s", copy.SourceBucketName, copy.SourceObjectName)
|
||||
err = s3.CopyObject(copy.BucketName, copy.ObjectName, objectSource, copyConds)
|
||||
if err != nil {
|
||||
msg := "error copying object"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -47,30 +45,26 @@ func CreateObjectHandler(s3 S3Client) http.Handler {
|
|||
|
||||
err = json.NewEncoder(w).Encode(copy)
|
||||
if err != nil {
|
||||
msg := "error encoding json"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err := r.ParseMultipartForm(32 << 20)
|
||||
if err != nil {
|
||||
msg := "error parsing form"
|
||||
handleHTTPError(w, msg, err, http.StatusUnprocessableEntity)
|
||||
handleHTTPError(w, http.StatusUnprocessableEntity, err)
|
||||
return
|
||||
}
|
||||
|
||||
file, handler, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
msg := "error getting form file"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = s3.PutObject(vars["bucketName"], handler.Filename, file, contentTypeOctetStream)
|
||||
if err != nil {
|
||||
msg := "error putting object"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@ func DeleteBucketHandler(s3 S3Client) http.Handler {
|
|||
|
||||
err := s3.RemoveBucket(vars["bucketName"])
|
||||
if err != nil {
|
||||
msg := "error removing bucket"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -13,21 +13,21 @@ func TestDeleteBucketHandler(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
|
||||
tests := map[string]struct {
|
||||
s3 S3Client
|
||||
expectedStatusCode int
|
||||
expectedBody string
|
||||
s3 S3Client
|
||||
expectedStatusCode int
|
||||
expectedBodyContains string
|
||||
}{
|
||||
"success": {
|
||||
s3: &S3ClientMock{},
|
||||
expectedStatusCode: http.StatusNoContent,
|
||||
expectedBody: "",
|
||||
s3: &S3ClientMock{},
|
||||
expectedStatusCode: http.StatusNoContent,
|
||||
expectedBodyContains: "",
|
||||
},
|
||||
"s3 error": {
|
||||
s3: &S3ClientMock{
|
||||
Err: errors.New("mocked S3 error"),
|
||||
},
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBody: "error removing bucket\n",
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBodyContains: http.StatusText(http.StatusInternalServerError),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,6 @@ func TestDeleteBucketHandler(t *testing.T) {
|
|||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, rr.Code, tcID)
|
||||
assert.Equal(tc.expectedBody, rr.Body.String(), tcID)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains, tcID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,8 +13,7 @@ func DeleteObjectHandler(s3 S3Client) http.Handler {
|
|||
|
||||
err := s3.RemoveObject(vars["bucketName"], vars["objectName"])
|
||||
if err != nil {
|
||||
msg := "error removing object"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -13,21 +13,21 @@ func TestDeleteObjectHandler(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
|
||||
tests := map[string]struct {
|
||||
s3 S3Client
|
||||
expectedStatusCode int
|
||||
expectedBody string
|
||||
s3 S3Client
|
||||
expectedStatusCode int
|
||||
expectedBodyContains string
|
||||
}{
|
||||
"success": {
|
||||
s3: &S3ClientMock{},
|
||||
expectedStatusCode: http.StatusNoContent,
|
||||
expectedBody: "",
|
||||
s3: &S3ClientMock{},
|
||||
expectedStatusCode: http.StatusNoContent,
|
||||
expectedBodyContains: "",
|
||||
},
|
||||
"s3 error": {
|
||||
s3: &S3ClientMock{
|
||||
Err: errors.New("mocked S3 error"),
|
||||
},
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBody: "error removing object\n",
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBodyContains: http.StatusText(http.StatusInternalServerError),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,6 @@ func TestDeleteObjectHandler(t *testing.T) {
|
|||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(tc.expectedStatusCode, rr.Code, tcID)
|
||||
assert.Equal(tc.expectedBody, rr.Body.String(), tcID)
|
||||
assert.Contains(rr.Body.String(), tc.expectedBodyContains, tcID)
|
||||
}
|
||||
}
|
||||
|
|
24
errors.go
Normal file
24
errors.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Common error messages within the app
|
||||
const (
|
||||
ErrBucketDoesNotExist = "The specified bucket does not exist."
|
||||
ErrKeyDoesNotExist = "The specified key does not exist."
|
||||
)
|
||||
|
||||
// handleHTTPError handles HTTP errors
|
||||
func handleHTTPError(w http.ResponseWriter, statusCode int, err error) {
|
||||
msg := http.StatusText(statusCode)
|
||||
http.Error(w, msg, statusCode)
|
||||
|
||||
logMsg := msg
|
||||
if err != nil {
|
||||
logMsg = logMsg + ": " + err.Error()
|
||||
}
|
||||
log.Println(logMsg)
|
||||
}
|
|
@ -16,8 +16,7 @@ func GetObjectHandler(s3 S3Client) http.Handler {
|
|||
|
||||
object, err := s3.GetObject(vars["bucketName"], objectName)
|
||||
if err != nil {
|
||||
msg := "error getting object"
|
||||
handleHTTPError(w, msg, err, http.StatusInternalServerError)
|
||||
handleHTTPError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -26,18 +25,11 @@ func GetObjectHandler(s3 S3Client) http.Handler {
|
|||
|
||||
_, err = io.Copy(w, object)
|
||||
if err != nil {
|
||||
msg := "error copying object"
|
||||
code := http.StatusInternalServerError
|
||||
if err.Error() == "The specified key does not exist." {
|
||||
msg = "object not found"
|
||||
if err.Error() == ErrBucketDoesNotExist || err.Error() == ErrKeyDoesNotExist {
|
||||
code = http.StatusNotFound
|
||||
}
|
||||
if err.Error() == "The specified bucket does not exist." {
|
||||
msg = "bucket not found"
|
||||
code = http.StatusNotFound
|
||||
}
|
||||
|
||||
handleHTTPError(w, msg, err, code)
|
||||
handleHTTPError(w, code, err)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
|
|
@ -29,7 +29,7 @@ func TestGetObjectHandler(t *testing.T) {
|
|||
bucketName: "testBucket",
|
||||
objectName: "testObject",
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
expectedBodyCountains: "error getting object\n",
|
||||
expectedBodyCountains: http.StatusText(http.StatusInternalServerError),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// handleHTTPError handles HTTP errors
|
||||
func handleHTTPError(w http.ResponseWriter, msg string, err error, statusCode int) {
|
||||
http.Error(w, msg, statusCode)
|
||||
if err != nil {
|
||||
log.Println(msg+":", err.Error())
|
||||
} else {
|
||||
log.Println(msg)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue