diff options
| author | Stefan Majewsky <stefan.majewsky@sap.com> | 2023-10-25 13:49:14 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-25 13:49:14 +0200 |
| commit | c48895200c34150e8ed0e6c726d6123310e88804 (patch) | |
| tree | 3ae8d6b34cbed323d0936503ecd579695c762249 | |
| parent | 1bc6c5a6fcf5bf0f52a960b6df87b6bd04e10956 (diff) | |
| parent | 6f2956376fa67c4fd3abbed65d1ec20bea2b9e00 (diff) | |
| download | go-schwift-c48895200c34150e8ed0e6c726d6123310e88804.tar.gz | |
Merge pull request #16 from SuperSandro2000/fix-lints
Fix remaining lints
| -rw-r--r-- | bulk.go | 3 | ||||
| -rw-r--r-- | errors.go | 4 | ||||
| -rw-r--r-- | internal/errext/errext.go | 26 | ||||
| -rw-r--r-- | largeobject.go | 6 | ||||
| -rw-r--r-- | object.go | 26 | ||||
| -rw-r--r-- | request.go | 2 | ||||
| -rw-r--r-- | tests/bulk_upload_test.go | 5 |
7 files changed, 54 insertions, 18 deletions
@@ -28,6 +28,7 @@ import ( "strings" "github.com/majewsky/schwift/capabilities" + "github.com/majewsky/schwift/internal/errext" ) // BulkUploadFormat enumerates possible archive formats for Container.BulkUpload(). @@ -214,7 +215,7 @@ func (a *Account) bulkDeleteSingle(objects []*Object, containers []*Container, o numNotFound++ return nil } - if statusErr, ok := err.(UnexpectedStatusCodeError); ok { + if statusErr, ok := errext.As[UnexpectedStatusCodeError](err); ok { errs = append(errs, BulkObjectError{ ContainerName: containerName, ObjectName: objectName, @@ -24,6 +24,8 @@ import ( "net/http" "strconv" "strings" + + "github.com/majewsky/schwift/internal/errext" ) var ( @@ -148,7 +150,7 @@ func (e BulkError) Error() string { // // It is safe to pass a nil error, in which case Is() always returns false. func Is(err error, code int) bool { - if e, ok := err.(UnexpectedStatusCodeError); ok { + if e, ok := errext.As[UnexpectedStatusCodeError](err); ok { return e.ActualResponse.StatusCode == code } return false diff --git a/internal/errext/errext.go b/internal/errext/errext.go new file mode 100644 index 0000000..3655ba7 --- /dev/null +++ b/internal/errext/errext.go @@ -0,0 +1,26 @@ +package errext + +import "errors" + +// vendored from https://github.com/sapcc/go-bits/blob/master/errext/errext.go (also licensed Apache 2.0) to prevent go.mod go bump to 1.21 + +// As is a variant of errors.As() that leverages generics to present a nicer interface. +// +// //this code: +// var perr os.PathError +// if errors.As(err, &perr) { +// handle(perr) +// } +// //can be rewritten as: +// if perr, ok := errext.As[os.PathError](err); ok { +// handle(perr) +// } +// +// This is sometimes more verbose (like in this example), but allows to scope +// the specific error variable to the condition's then-branch, and also looks +// more idiomatic to developers already familiar with type casts. +func As[T error](err error) (T, bool) { + var result T + ok := errors.As(err, &result) + return result, ok +} diff --git a/largeobject.go b/largeobject.go index 83deddf..4def0d0 100644 --- a/largeobject.go +++ b/largeobject.go @@ -414,13 +414,13 @@ func (o *Object) AsNewLargeObject(sopts SegmentingOptions, topts *TruncateOption //with the old segments if topts != nil && topts.DeleteSegments { lo, err := o.AsLargeObject() - switch err { - case nil: + switch { + case err == nil: err := lo.Truncate(topts) if err != nil { return nil, err } - case ErrNotLarge: + case errors.Is(err, ErrNotLarge): //not an error, continue down below default: return nil, err //unexpected error @@ -25,6 +25,7 @@ import ( "crypto/sha1" //nolint:gosec // Used by swift "crypto/sha256" "encoding/hex" + "errors" "fmt" "hash" "io" @@ -135,6 +136,7 @@ func (o *Object) fetchHeaders(opts *RequestOptions) (*ObjectHeaders, error) { if err != nil { return nil, err } + defer resp.Body.Close() headers := ObjectHeaders{headersFromHTTP(resp.Header)} return &headers, headers.Validate() @@ -147,7 +149,7 @@ func (o *Object) fetchHeaders(opts *RequestOptions) (*ObjectHeaders, error) { // // A successful POST request implies Invalidate() since it may change metadata. func (o *Object) Update(headers ObjectHeaders, opts *RequestOptions) error { - _, err := Request{ + resp, err := Request{ Method: "POST", ContainerName: o.c.name, ObjectName: o.name, @@ -156,6 +158,7 @@ func (o *Object) Update(headers ObjectHeaders, opts *RequestOptions) error { }.Do(o.c.a.backend) if err == nil { o.Invalidate() + resp.Body.Close() } return err } @@ -245,10 +248,10 @@ func (o *Object) Upload(content io.Reader, opts *UploadOptions, ropts *RequestOp //chance of an inconsistent state following an upload error var err error lo, err = o.AsLargeObject() - switch err { - case nil: + switch { + case err == nil: //okay, delete segments at the end - case ErrNotLarge: + case errors.Is(err, ErrNotLarge): //okay, do not try to delete segments lo = nil default: @@ -270,6 +273,7 @@ func (o *Object) Upload(content io.Reader, opts *UploadOptions, ropts *RequestOp return err } o.Invalidate() + defer resp.Body.Close() if hasher != nil { expectedEtag := hex.EncodeToString(hasher.Sum(nil)) @@ -393,13 +397,13 @@ func (o *Object) Delete(opts *DeleteOptions, ropts *RequestOptions) error { } if exists { lo, err := o.AsLargeObject() - switch err { - case nil: + switch { + case err == nil: //is large object - delete segments and the object itself in one step _, _, err := o.c.a.BulkDelete(append(lo.SegmentObjects(), o), nil, nil) o.Invalidate() return err - case ErrNotLarge: + case errors.Is(err, ErrNotLarge): //not a large object - use regular DELETE request default: //unexpected error @@ -408,7 +412,7 @@ func (o *Object) Delete(opts *DeleteOptions, ropts *RequestOptions) error { } } - _, err := Request{ + resp, err := Request{ Method: "DELETE", ContainerName: o.c.name, ObjectName: o.name, @@ -417,6 +421,7 @@ func (o *Object) Delete(opts *DeleteOptions, ropts *RequestOptions) error { }.Do(o.c.a.backend) if err == nil { o.Invalidate() + resp.Body.Close() } return err } @@ -453,7 +458,7 @@ func (o *Object) Download(opts *RequestOptions) DownloadedObject { ObjectName: o.name, Options: opts, ExpectStatusCodes: []int{http.StatusOK}, - }.Do(o.c.a.backend) + }.Do(o.c.a.backend) //nolint:bodyclose // body is returned and must be closed by the user var body io.ReadCloser if err == nil { newHeaders := ObjectHeaders{headersFromHTTP(resp.Header)} @@ -498,7 +503,7 @@ func (o *Object) CopyTo(target *Object, opts *CopyOptions, ropts *RequestOptions } } - _, err := Request{ + resp, err := Request{ Method: "COPY", ContainerName: o.c.name, ObjectName: o.name, @@ -508,6 +513,7 @@ func (o *Object) CopyTo(target *Object, opts *CopyOptions, ropts *RequestOptions }.Do(o.c.a.backend) if err == nil { target.Invalidate() + resp.Body.Close() } return err } @@ -40,7 +40,7 @@ import ( type RequestOptions struct { Headers Headers Values url.Values - Context context.Context + Context context.Context //nolint: containedctx // ignored for now to not break the API } func cloneRequestOptions(orig *RequestOptions, additional Headers) *RequestOptions { diff --git a/tests/bulk_upload_test.go b/tests/bulk_upload_test.go index d810cf5..0bdcb4e 100644 --- a/tests/bulk_upload_test.go +++ b/tests/bulk_upload_test.go @@ -25,6 +25,7 @@ import ( "testing" "github.com/majewsky/schwift" + "github.com/majewsky/schwift/internal/errext" ) func TestBulkUploadSuccess(t *testing.T) { @@ -62,7 +63,7 @@ func TestBulkUploadArchiveError(t *testing.T) { ) expectInt(t, n, 0) expectError(t, err, "400 Bad Request: Invalid Tar File: truncated header") - bulkErr := err.(schwift.BulkError) //nolint:errcheck + bulkErr, _ := errext.As[schwift.BulkError](err) expectInt(t, bulkErr.StatusCode, 400) expectString(t, bulkErr.OverallError, "Invalid Tar File: truncated header") expectInt(t, len(bulkErr.ObjectErrors), 0) @@ -87,7 +88,7 @@ func TestBulkUploadObjectError(t *testing.T) { ) expectInt(t, n, 1) expectError(t, err, "400 Bad Request (+1 object errors)") - bulkErr := err.(schwift.BulkError) //nolint:errcheck + bulkErr, _ := errext.As[schwift.BulkError](err) expectInt(t, len(bulkErr.ObjectErrors), 1) expectString(t, bulkErr.ObjectErrors[0].ContainerName, c.Name()) expectInt(t, bulkErr.ObjectErrors[0].StatusCode, 400) |
