diff --git a/modules/util/error.go b/modules/util/error.go index 0f3597147ceaa..7636d72f168d1 100644 --- a/modules/util/error.go +++ b/modules/util/error.go @@ -6,6 +6,8 @@ package util import ( "errors" "fmt" + "io" + "net/http" ) // Common Errors forming the base of our error system @@ -17,8 +19,27 @@ var ( ErrPermissionDenied = errors.New("permission denied") ErrAlreadyExist = errors.New("resource already exists") ErrNotExist = errors.New("resource does not exist") + ErrPayloadTooLarge = errors.New("payload too large") + ErrLimitExceeded = errors.New("limit exceeded") ) +// Automatically get HTTP status from error. +func StatusFromError(err error) int { + switch { + case errors.Is(err, ErrNotExist): + return http.StatusNotFound + case errors.Is(err, ErrAlreadyExist) || errors.Is(err, ErrLimitExceeded): + return http.StatusConflict + case errors.Is(err, ErrPayloadTooLarge): + return http.StatusRequestEntityTooLarge + case errors.Is(err, ErrInvalidArgument) || errors.Is(err, io.EOF): + return http.StatusBadRequest + case errors.Is(err, ErrPermissionDenied): + return http.StatusForbidden + } + return http.StatusInternalServerError +} + // SilentWrap provides a simple wrapper for a wrapped error where the wrapped error message plays no part in the error message // Especially useful for "untyped" errors created with "errors.New(…)" that can be classified as 'invalid argument', 'permission denied', 'exists already', or 'does not exist' type SilentWrap struct { @@ -63,3 +84,13 @@ func NewAlreadyExistErrorf(message string, args ...any) error { func NewNotExistErrorf(message string, args ...any) error { return NewSilentWrapErrorf(ErrNotExist, message, args...) } + +// NewPayloadTooLargeErrorf returns an error that formats as the given text but unwraps as an ErrPayloadTooLarge +func NewPayloadTooLargeErrorf(message string, args ...any) error { + return NewSilentWrapErrorf(ErrPayloadTooLarge, message, args...) +} + +// NewLimitExceededErrorf returns an error that formats as the given text but unwraps as an ErrLimitExceeded +func NewLimitExceededErrorf(message string, args ...any) error { + return NewSilentWrapErrorf(ErrLimitExceeded, message, args...) +} diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go index bb14c5163a436..15bc99f3330b5 100644 --- a/routers/api/packages/alpine/alpine.go +++ b/routers/api/packages/alpine/alpine.go @@ -7,7 +7,6 @@ import ( "crypto/x509" "encoding/hex" "encoding/pem" - "errors" "fmt" "io" "net/http" @@ -24,7 +23,8 @@ import ( alpine_service "code.gitea.io/gitea/services/packages/alpine" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -33,25 +33,25 @@ func apiError(ctx *context.Context, status int, obj any) { func GetRepositoryKey(ctx *context.Context) { _, pub, err := alpine_service.GetOrCreateKeyPair(ctx, ctx.Package.Owner.ID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pubPem, _ := pem.Decode([]byte(pub)) if pubPem == nil { - apiError(ctx, http.StatusInternalServerError, "failed to decode private key pem") + apiError(ctx, "failed to decode private key pem") return } pubKey, err := x509.ParsePKIXPublicKey(pubPem.Bytes) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } fingerprint, err := util.CreatePublicKeyFingerprint(pubKey) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -64,7 +64,7 @@ func GetRepositoryKey(ctx *context.Context) { func GetRepositoryFile(ctx *context.Context) { pv, err := alpine_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -77,11 +77,7 @@ func GetRepositoryFile(ctx *context.Context) { }, ) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -92,13 +88,13 @@ func UploadPackageFile(ctx *context.Context) { branch := strings.TrimSpace(ctx.Params("branch")) repository := strings.TrimSpace(ctx.Params("repository")) if branch == "" || repository == "" { - apiError(ctx, http.StatusBadRequest, "invalid branch or repository") + apiError(ctx, "invalid branch or repository", http.StatusBadRequest) return } upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if close { @@ -107,29 +103,25 @@ func UploadPackageFile(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() pck, err := alpine_module.ParsePackage(buf) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) || err == io.EOF { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } fileMetadataRaw, err := json.Marshal(pck.FileMetadata) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -162,19 +154,12 @@ func UploadPackageFile(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if err := alpine_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, branch, repository, pck.FileMetadata.Architecture); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -189,21 +174,17 @@ func DownloadPackageFile(ctx *context.Context) { CompositeKey: fmt.Sprintf("%s|%s|%s", ctx.Params("branch"), ctx.Params("repository"), ctx.Params("architecture")), }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) != 1 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -220,25 +201,21 @@ func DeletePackageFile(ctx *context.Context) { CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, architecture), }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) != 1 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } if err := packages_service.RemovePackageFileAndVersionIfUnreferenced(ctx, ctx.Doer, pfs[0]); err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if err := alpine_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, branch, repository, architecture); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } diff --git a/routers/api/packages/cargo/cargo.go b/routers/api/packages/cargo/cargo.go index 8f1e965c9a399..41747ddb910ad 100644 --- a/routers/api/packages/cargo/cargo.go +++ b/routers/api/packages/cargo/cargo.go @@ -4,7 +4,6 @@ package cargo import ( - "errors" "fmt" "net/http" "strconv" @@ -35,7 +34,8 @@ type StatusMessage struct { Message string `json:"detail"` } -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, StatusResponse{ OK: false, @@ -56,21 +56,17 @@ func RepositoryConfig(ctx *context.Context) { func EnumeratePackageVersions(ctx *context.Context) { p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.TypeCargo, ctx.Params("package")) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } b, err := cargo_service.BuildPackageIndex(ctx, p) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if b == nil { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } @@ -115,13 +111,13 @@ func SearchPackages(ctx *context.Context) { }, ) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -180,11 +176,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -197,19 +189,19 @@ func UploadPackage(ctx *context.Context) { cp, err := cargo_module.ParsePackage(ctx.Req.Body) if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } buf, err := packages_module.CreateHashedBufferFromReader(cp.Content) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() if buf.Size() != cp.ContentSize { - apiError(ctx, http.StatusBadRequest, "invalid content size") + apiError(ctx, "invalid content size", http.StatusBadRequest) return } @@ -239,14 +231,7 @@ func UploadPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -254,8 +239,7 @@ func UploadPackage(ctx *context.Context) { if err := packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil { log.Error("Rollback creation of package version: %v", err) } - - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -275,21 +259,17 @@ func UnyankPackage(ctx *context.Context) { func yankPackage(ctx *context.Context, yank bool) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeCargo, ctx.Params("package"), ctx.Params("version")) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pps, err := packages_model.GetPropertiesByName(ctx, packages_model.PropertyTypeVersion, pv.ID, cargo_module.PropertyYanked) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pps) == 0 { - apiError(ctx, http.StatusInternalServerError, "Property not found") + apiError(ctx, "Property not found") return } @@ -297,12 +277,12 @@ func yankPackage(ctx *context.Context, yank bool) { pp.Value = strconv.FormatBool(yank) if err := packages_model.UpdateProperty(ctx, pp); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if err := cargo_service.UpdatePackageIndexIfExists(ctx, ctx.Doer, ctx.Package.Owner, pv.PackageID); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } diff --git a/routers/api/packages/chef/chef.go b/routers/api/packages/chef/chef.go index f1e9ae12d816c..8a3ff741216f5 100644 --- a/routers/api/packages/chef/chef.go +++ b/routers/api/packages/chef/chef.go @@ -4,7 +4,6 @@ package chef import ( - "errors" "fmt" "io" "net/http" @@ -24,7 +23,8 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) type Error struct { ErrorMessages []string `json:"error_messages"` } @@ -43,13 +43,13 @@ func PackagesUniverse(ctx *context.Context) { IsInternal: util.OptionalBoolFalse, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -101,13 +101,13 @@ func EnumeratePackages(ctx *context.Context) { pvs, total, err := packages_model.SearchLatestVersions(ctx, opts) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -153,17 +153,17 @@ func PackageMetadata(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -215,17 +215,13 @@ func PackageVersionMetadata(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, packageName, packageVersion) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -258,30 +254,26 @@ func PackageVersionMetadata(ctx *context.Context) { func UploadPackage(ctx *context.Context) { file, _, err := ctx.Req.FormFile("tarball") if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } defer file.Close() buf, err := packages_module.CreateHashedBufferFromReader(file) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() pck, err := chef_module.ParsePackage(buf) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -308,14 +300,7 @@ func UploadPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -326,17 +311,13 @@ func UploadPackage(ctx *context.Context) { func DownloadPackage(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, ctx.Params("name"), ctx.Params("version")) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -344,7 +325,7 @@ func DownloadPackage(ctx *context.Context) { s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -367,11 +348,7 @@ func DeletePackageVersion(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -382,18 +359,18 @@ func DeletePackageVersion(ctx *context.Context) { func DeletePackage(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, ctx.Params("name")) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, err, http.StatusNotFound) return } for _, pv := range pvs { if err := packages_service.RemovePackageVersion(ctx, ctx.Doer, pv); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go index 0551093cd19f2..7fd9cfd873133 100644 --- a/routers/api/packages/composer/composer.go +++ b/routers/api/packages/composer/composer.go @@ -4,7 +4,6 @@ package composer import ( - "errors" "fmt" "io" "net/http" @@ -26,7 +25,8 @@ import ( "github.com/hashicorp/go-version" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { type Error struct { Status int `json:"status"` @@ -77,7 +77,7 @@ func SearchPackages(ctx *context.Context) { pvs, total, err := packages_model.SearchLatestVersions(ctx, opts) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -85,7 +85,7 @@ func SearchPackages(ctx *context.Context) { if len(pvs) == paginator.PageSize { u, err := url.Parse(setting.AppURL + "api/packages/" + ctx.Package.Owner.Name + "/composer/search.json") if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } q := u.Query() @@ -102,7 +102,7 @@ func SearchPackages(ctx *context.Context) { pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -116,7 +116,7 @@ func SearchPackages(ctx *context.Context) { func EnumeratePackages(ctx *context.Context) { ps, err := packages_model.GetPackagesByType(ctx, ctx.Package.Owner.ID, packages_model.TypeComposer) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -138,17 +138,17 @@ func PackageMetadata(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeComposer, vendorName+"/"+projectName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, packages_model.ErrPackageNotExist) + apiError(ctx, packages_model.ErrPackageNotExist) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -175,11 +175,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -190,30 +186,26 @@ func DownloadPackageFile(ctx *context.Context) { func UploadPackage(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() cp, err := composer_module.ParsePackage(buf, buf.Size()) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if cp.Version == "" { v, err := version.NewVersion(ctx.FormTrim("version")) if err != nil { - apiError(ctx, http.StatusBadRequest, composer_module.ErrInvalidVersion) + apiError(ctx, composer_module.ErrInvalidVersion) return } cp.Version = v.String() @@ -245,14 +237,7 @@ func UploadPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go index 4bf13222dc793..1871745c6f1d9 100644 --- a/routers/api/packages/conan/conan.go +++ b/routers/api/packages/conan/conan.go @@ -57,7 +57,8 @@ func jsonResponse(ctx *context.Context, status int, obj any) { } } -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { jsonResponse(ctx, status, map[string]string{ "message": message, @@ -79,7 +80,7 @@ func ExtractPathParameters(ctx *context.Context) { ctx.Params("recipe_revision"), ) if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } @@ -95,7 +96,7 @@ func ExtractPathParameters(ctx *context.Context) { ctx.Params("package_revision"), ) if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } } @@ -113,13 +114,13 @@ func Ping(ctx *context.Context) { // Authenticate creates an authentication token for the user func Authenticate(ctx *context.Context) { if ctx.Doer == nil { - apiError(ctx, http.StatusBadRequest, nil) + apiError(ctx, nil, http.StatusBadRequest) return } token, err := packages_service.CreateAuthorizationToken(ctx.Doer) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -154,11 +155,7 @@ func serveSnapshot(ctx *context.Context, fileKey string) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -167,11 +164,11 @@ func serveSnapshot(ctx *context.Context, fileKey string) { CompositeKey: fileKey, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) == 0 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } @@ -179,7 +176,7 @@ func serveSnapshot(ctx *context.Context, fileKey string) { for _, pf := range pfs { pb, err := packages_model.GetBlobByID(ctx, pf.BlobID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } files[pf.Name] = pb.HashMD5 @@ -215,11 +212,7 @@ func serveDownloadURLs(ctx *context.Context, fileKey, downloadURL string) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -228,12 +221,12 @@ func serveDownloadURLs(ctx *context.Context, fileKey, downloadURL string) { CompositeKey: fileKey, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) == 0 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } @@ -272,7 +265,7 @@ func serveUploadURLs(ctx *context.Context, fileFilter container.Set[string], upl var files map[string]int64 if err := json.NewDecoder(ctx.Req.Body).Decode(&files); err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } @@ -306,13 +299,13 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey filename := ctx.Params("filename") if !fileFilter.Contains(filename) { - apiError(ctx, http.StatusBadRequest, nil) + apiError(ctx, nil, http.StatusBadRequest) return } upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } if close { @@ -321,7 +314,7 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() @@ -364,23 +357,23 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey metadata, err := conan_module.ParseConanfile(buf) if err != nil { log.Error("Error parsing package metadata: %v", err) - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pv, err := packages_model.GetVersionByNameAndVersion(ctx, pci.Owner.ID, pci.PackageType, pci.Name, pci.Version) if err != nil && err != packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if pv != nil { raw, err := json.Marshal(metadata) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pv.MetadataJSON = string(raw) if err := packages_model.UpdateVersion(ctx, pv); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } else { @@ -390,19 +383,19 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey info, err := conan_module.ParseConaninfo(buf) if err != nil { log.Error("Error parsing conan info: %v", err) - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } raw, err := json.Marshal(info) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pfci.Properties[conan_module.PropertyPackageInfo] = string(raw) } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } @@ -413,14 +406,7 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey pfci, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -446,7 +432,7 @@ func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKe filename := ctx.Params("filename") if !fileFilter.Contains(filename) { - apiError(ctx, http.StatusBadRequest, nil) + apiError(ctx, nil, http.StatusBadRequest) return } @@ -464,11 +450,7 @@ func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKe }, ) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -480,11 +462,7 @@ func DeleteRecipeV1(ctx *context.Context) { rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference) if err := deleteRecipeOrPackage(ctx, rref, true, nil, false); err != nil { - if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } ctx.Status(http.StatusOK) @@ -495,11 +473,7 @@ func DeleteRecipeV2(ctx *context.Context) { rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference) if err := deleteRecipeOrPackage(ctx, rref, rref.Revision == "", nil, false); err != nil { - if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } ctx.Status(http.StatusOK) @@ -515,13 +489,13 @@ func DeletePackageV1(ctx *context.Context) { var ids *PackageReferences if err := json.NewDecoder(ctx.Req.Body).Decode(&ids); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } revisions, err := conan_model.GetRecipeRevisions(ctx, ctx.Package.Owner.ID, rref) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } for _, revision := range revisions { @@ -530,7 +504,7 @@ func DeletePackageV1(ctx *context.Context) { var references []*conan_model.PropertyValue if len(ids.References) == 0 { if references, err = conan_model.GetPackageReferences(ctx, ctx.Package.Owner.ID, currentRref); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } else { @@ -542,11 +516,7 @@ func DeletePackageV1(ctx *context.Context) { for _, reference := range references { pref, _ := conan_module.NewPackageReference(currentRref, reference.Value, conan_module.DefaultRevision) if err := deleteRecipeOrPackage(ctx, currentRref, true, pref, true); err != nil { - if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } } @@ -561,11 +531,7 @@ func DeletePackageV2(ctx *context.Context) { if pref != nil { // has package reference if err := deleteRecipeOrPackage(ctx, rref, false, pref, pref.Revision == ""); err != nil { - if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) } else { ctx.Status(http.StatusOK) } @@ -574,11 +540,11 @@ func DeletePackageV2(ctx *context.Context) { references, err := conan_model.GetPackageReferences(ctx, ctx.Package.Owner.ID, rref) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(references) == 0 { - apiError(ctx, http.StatusNotFound, conan_model.ErrPackageReferenceNotExist) + apiError(ctx, conan_model.ErrPackageReferenceNotExist) return } @@ -586,11 +552,7 @@ func DeletePackageV2(ctx *context.Context) { pref, _ := conan_module.NewPackageReference(rref, reference.Value, conan_module.DefaultRevision) if err := deleteRecipeOrPackage(ctx, rref, false, pref, true); err != nil { - if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } } @@ -671,7 +633,7 @@ func ListRecipeRevisions(ctx *context.Context) { revisions, err := conan_model.GetRecipeRevisions(ctx, ctx.Package.Owner.ID, rref) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -684,7 +646,7 @@ func ListPackageRevisions(ctx *context.Context) { revisions, err := conan_model.GetPackageRevisions(ctx, ctx.Package.Owner.ID, pref) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -698,7 +660,7 @@ type revisionInfo struct { func listRevisions(ctx *context.Context, revisions []*conan_model.PropertyValue) { if len(revisions) == 0 { - apiError(ctx, http.StatusNotFound, conan_model.ErrRecipeReferenceNotExist) + apiError(ctx, conan_model.ErrRecipeReferenceNotExist) return } @@ -720,11 +682,7 @@ func LatestRecipeRevision(ctx *context.Context) { revision, err := conan_model.GetLastRecipeRevision(ctx, ctx.Package.Owner.ID, rref) if err != nil { - if err == conan_model.ErrRecipeReferenceNotExist || err == conan_model.ErrPackageReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -737,11 +695,7 @@ func LatestPackageRevision(ctx *context.Context) { revision, err := conan_model.GetLastPackageRevision(ctx, ctx.Package.Owner.ID, pref) if err != nil { - if err == conan_model.ErrRecipeReferenceNotExist || err == conan_model.ErrPackageReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -767,11 +721,7 @@ func listRevisionFiles(ctx *context.Context, fileKey string) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -780,11 +730,11 @@ func listRevisionFiles(ctx *context.Context, fileKey string) { CompositeKey: fileKey, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) == 0 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } diff --git a/routers/api/packages/conan/search.go b/routers/api/packages/conan/search.go index 2bcf9df162b98..7b1c9a4b1d718 100644 --- a/routers/api/packages/conan/search.go +++ b/routers/api/packages/conan/search.go @@ -27,7 +27,7 @@ func SearchRecipes(ctx *context.Context) { results, err := conan_model.SearchRecipes(ctx, opts) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -76,26 +76,18 @@ func searchPackages(ctx *context.Context, searchAllRevisions bool) { if !searchAllRevisions && rref.Revision == "" { lastRevision, err := conan_model.GetLastRecipeRevision(ctx, ctx.Package.Owner.ID, rref) if err != nil { - if err == conan_model.ErrRecipeReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } rref = rref.WithRevision(lastRevision.Value) } else { has, err := conan_model.RecipeExists(ctx, ctx.Package.Owner.ID, rref) if err != nil { - if err == conan_model.ErrRecipeReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if !has { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } } @@ -105,7 +97,7 @@ func searchPackages(ctx *context.Context, searchAllRevisions bool) { var err error recipeRevisions, err = conan_model.GetRecipeRevisions(ctx, ctx.Package.Owner.ID, rref) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } @@ -119,11 +111,7 @@ func searchPackages(ctx *context.Context, searchAllRevisions bool) { } packageReferences, err := conan_model.GetPackageReferences(ctx, ctx.Package.Owner.ID, currentRef) if err != nil { - if err == conan_model.ErrRecipeReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } for _, packageReference := range packageReferences { @@ -133,26 +121,18 @@ func searchPackages(ctx *context.Context, searchAllRevisions bool) { pref, _ := conan_module.NewPackageReference(currentRef, packageReference.Value, "") lastPackageRevision, err := conan_model.GetLastPackageRevision(ctx, ctx.Package.Owner.ID, pref) if err != nil { - if err == conan_model.ErrPackageReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } pref = pref.WithRevision(lastPackageRevision.Value) infoRaw, err := conan_model.GetPackageInfo(ctx, ctx.Package.Owner.ID, pref) if err != nil { - if err == conan_model.ErrPackageReferenceNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } var info *conan_module.Conaninfo if err := json.Unmarshal([]byte(infoRaw), &info); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } result[pref.Reference] = info diff --git a/routers/api/packages/conda/conda.go b/routers/api/packages/conda/conda.go index 0bee7baa96f76..66d7f6f945944 100644 --- a/routers/api/packages/conda/conda.go +++ b/routers/api/packages/conda/conda.go @@ -4,7 +4,6 @@ package conda import ( - "errors" "fmt" "io" "net/http" @@ -17,14 +16,14 @@ import ( "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" conda_module "code.gitea.io/gitea/modules/packages/conda" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" "github.com/dsnet/compress/bzip2" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, struct { Reason string `json:"reason"` @@ -79,12 +78,12 @@ func EnumeratePackages(ctx *context.Context) { Subdir: repoData.Info.Subdir, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) == 0 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } @@ -95,13 +94,13 @@ func EnumeratePackages(ctx *context.Context) { if !exists { pv, err := packages_model.GetVersionByID(ctx, pf.VersionID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pd, err = packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -118,7 +117,7 @@ func EnumeratePackages(ctx *context.Context) { var fileMetadata *conda_module.FileMetadata if err := json.Unmarshal([]byte(pfd.Properties.GetByName(conda_module.PropertyMetadata)), &fileMetadata); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -158,7 +157,7 @@ func EnumeratePackages(ctx *context.Context) { zw, err := bzip2.NewWriter(w, nil) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer zw.Close() @@ -176,7 +175,7 @@ func EnumeratePackages(ctx *context.Context) { func UploadPackageFile(ctx *context.Context) { upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if close { @@ -185,7 +184,7 @@ func UploadPackageFile(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() @@ -197,16 +196,12 @@ func UploadPackageFile(ctx *context.Context) { pck, err = conda_module.ParsePackageConda(buf, buf.Size()) } if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -224,7 +219,7 @@ func UploadPackageFile(ctx *context.Context) { fileMetadataRaw, err := json.Marshal(pck.FileMetadata) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -260,14 +255,7 @@ func UploadPackageFile(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -282,12 +270,12 @@ func DownloadPackageFile(ctx *context.Context) { Filename: ctx.Params("filename"), }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) != 1 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } @@ -295,7 +283,7 @@ func DownloadPackageFile(ctx *context.Context) { s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 62eec3064cdf9..97d657273bb9e 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -85,47 +85,45 @@ func jsonResponse(ctx *context.Context, status int, obj any) { } } -func apiError(ctx *context.Context, status int, err error) { - helper.LogAndProcessError(ctx, status, err, func(message string) { - setResponseHeaders(ctx.Resp, &containerHeaders{ - Status: status, +func apiError(ctx *context.Context, err error) { + switch err := err.(type) { + case *Error: + helper.LogAndProcessError(ctx, err.StatusCode, err, nil) + jsonResponse(ctx, err.StatusCode, Errors{ + Errors: []Error{ + { + Code: err.Code, + Message: err.Message, + }, + }, + }) + default: + status := helper.FormResponseCode(err) + helper.LogAndProcessError(ctx, status, err, func(s string) { + jsonResponse(ctx, status, Errors{ + Errors: []Error{ + { + Code: "UNKNOWN", + Message: s, + }, + }, + }) }) - }) -} - -// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#error-codes -func apiErrorDefined(ctx *context.Context, err *namedError) { - type ContainerError struct { - Code string `json:"code"` - Message string `json:"message"` - } - - type ContainerErrors struct { - Errors []ContainerError `json:"errors"` } - - jsonResponse(ctx, err.StatusCode, ContainerErrors{ - Errors: []ContainerError{ - { - Code: err.Code, - Message: err.Message, - }, - }, - }) } // ReqContainerAccess is a middleware which checks the current user valid (real user or ghost for anonymous access) func ReqContainerAccess(ctx *context.Context) { if ctx.Doer == nil { ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+setting.AppURL+`v2/token",service="container_registry",scope="*"`) - apiErrorDefined(ctx, errUnauthorized) + apiError(ctx, errUnauthorized) } } // VerifyImageName is a middleware which checks if the image name is allowed func VerifyImageName(ctx *context.Context) { if !imageNamePattern.MatchString(ctx.Params("image")) { - apiErrorDefined(ctx, errNameInvalid) + apiError(ctx, errNameInvalid) } } @@ -147,7 +145,7 @@ func Authenticate(ctx *context.Context) { token, err := packages_service.CreateAuthorizationToken(u) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -166,7 +164,7 @@ func GetRepositoryList(ctx *context.Context) { repositories, err := container_model.GetRepositories(ctx, ctx.Doer, n, last) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -205,13 +203,13 @@ func InitiateUploadBlob(ctx *context.Context) { if blob != nil { accessible, err := packages_model.IsBlobAccessibleForUser(ctx, blob.Blob.ID, ctx.Doer) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if accessible { if err := mountBlob(ctx, &packages_service.PackageInfo{Owner: ctx.Package.Owner, Name: image}, blob.Blob); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -229,13 +227,13 @@ func InitiateUploadBlob(ctx *context.Context) { if digest != "" { buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() if digest != digestFromHashSummer(buf) { - apiErrorDefined(ctx, errDigestInvalid) + apiError(ctx, errDigestInvalid) return } @@ -249,12 +247,7 @@ func InitiateUploadBlob(ctx *context.Context) { Creator: ctx.Doer, }, ); err != nil { - switch err { - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -268,7 +261,7 @@ func InitiateUploadBlob(ctx *context.Context) { upload, err := packages_model.CreateBlobUpload(ctx) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -287,9 +280,9 @@ func GetUploadBlob(ctx *context.Context) { upload, err := packages_model.GetBlobUploadByID(ctx, uuid) if err != nil { if err == packages_model.ErrPackageBlobUploadNotExist { - apiErrorDefined(ctx, errBlobUploadUnknown) + apiError(ctx, errBlobUploadUnknown) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return } @@ -308,9 +301,9 @@ func UploadBlob(ctx *context.Context) { uploader, err := container_service.NewBlobUploader(ctx, ctx.Params("uuid")) if err != nil { if err == packages_model.ErrPackageBlobUploadNotExist { - apiErrorDefined(ctx, errBlobUploadUnknown) + apiError(ctx, errBlobUploadUnknown) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return } @@ -320,21 +313,21 @@ func UploadBlob(ctx *context.Context) { if contentRange != "" { start, end := 0, 0 if _, err := fmt.Sscanf(contentRange, "%d-%d", &start, &end); err != nil { - apiErrorDefined(ctx, errBlobUploadInvalid) + apiError(ctx, errBlobUploadInvalid) return } if int64(start) != uploader.Size() { - apiErrorDefined(ctx, errBlobUploadInvalid.WithStatusCode(http.StatusRequestedRangeNotSatisfiable)) + apiError(ctx, errBlobUploadInvalid.WithStatusCode(http.StatusRequestedRangeNotSatisfiable)) return } } else if uploader.Size() != 0 { - apiErrorDefined(ctx, errBlobUploadInvalid.WithMessage("Stream uploads after first write are not allowed")) + apiError(ctx, errBlobUploadInvalid.WithMessage("Stream uploads after first write are not allowed")) return } if err := uploader.Append(ctx, ctx.Req.Body); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -352,16 +345,16 @@ func EndUploadBlob(ctx *context.Context) { digest := ctx.FormTrim("digest") if digest == "" { - apiErrorDefined(ctx, errDigestInvalid) + apiError(ctx, errDigestInvalid) return } uploader, err := container_service.NewBlobUploader(ctx, ctx.Params("uuid")) if err != nil { if err == packages_model.ErrPackageBlobUploadNotExist { - apiErrorDefined(ctx, errBlobUploadUnknown) + apiError(ctx, errBlobUploadUnknown) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return } @@ -374,13 +367,13 @@ func EndUploadBlob(ctx *context.Context) { if ctx.Req.Body != nil { if err := uploader.Append(ctx, ctx.Req.Body); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } if digest != digestFromHashSummer(uploader) { - apiErrorDefined(ctx, errDigestInvalid) + apiError(ctx, errDigestInvalid) return } @@ -394,23 +387,17 @@ func EndUploadBlob(ctx *context.Context) { Creator: ctx.Doer, }, ); err != nil { - switch err { - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } - return + apiError(ctx, err) } if err := uploader.Close(); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } close = false if err := container_service.RemoveBlobUploadByID(ctx, uploader.ID); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -428,15 +415,15 @@ func CancelUploadBlob(ctx *context.Context) { _, err := packages_model.GetBlobUploadByID(ctx, uuid) if err != nil { if err == packages_model.ErrPackageBlobUploadNotExist { - apiErrorDefined(ctx, errBlobUploadUnknown) + apiError(ctx, errBlobUploadUnknown) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return } if err := container_service.RemoveBlobUploadByID(ctx, uuid); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -449,7 +436,7 @@ func getBlobFromContext(ctx *context.Context) (*packages_model.PackageFileDescri d := ctx.Params("digest") if digest.Digest(d).Validate() != nil { - return nil, container_model.ErrContainerBlobNotExist + return nil, errDigestInvalid } return workaroundGetContainerBlob(ctx, &container_model.BlobSearchOptions{ @@ -464,9 +451,9 @@ func HeadBlob(ctx *context.Context) { blob, err := getBlobFromContext(ctx) if err != nil { if err == container_model.ErrContainerBlobNotExist { - apiErrorDefined(ctx, errBlobUnknown) + apiError(ctx, errBlobUnknown) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return } @@ -483,9 +470,9 @@ func GetBlob(ctx *context.Context) { blob, err := getBlobFromContext(ctx) if err != nil { if err == container_model.ErrContainerBlobNotExist { - apiErrorDefined(ctx, errBlobUnknown) + apiError(ctx, errBlobUnknown) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return } @@ -498,12 +485,12 @@ func DeleteBlob(ctx *context.Context) { d := ctx.Params("digest") if digest.Digest(d).Validate() != nil { - apiErrorDefined(ctx, errBlobUnknown) + apiError(ctx, errBlobUnknown) return } if err := deleteBlob(ctx, ctx.Package.Owner.ID, ctx.Params("image"), d); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -526,37 +513,33 @@ func UploadManifest(ctx *context.Context) { } if mci.IsTagged && !referencePattern.MatchString(reference) { - apiErrorDefined(ctx, errManifestInvalid.WithMessage("Tag is invalid")) + apiError(ctx, errManifestInvalid.WithMessage("Tag is invalid")) return } maxSize := maxManifestSize + 1 buf, err := packages_module.CreateHashedBufferFromReaderWithSize(&io.LimitedReader{R: ctx.Req.Body, N: int64(maxSize)}, maxSize) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() if buf.Size() > maxManifestSize { - apiErrorDefined(ctx, errManifestInvalid.WithMessage("Manifest exceeds maximum size").WithStatusCode(http.StatusRequestEntityTooLarge)) + apiError(ctx, errManifestInvalid.WithMessage("Manifest exceeds maximum size").WithStatusCode(http.StatusRequestEntityTooLarge)) return } digest, err := processManifest(ctx, mci, buf) if err != nil { - var namedError *namedError - if errors.As(err, &namedError) { - apiErrorDefined(ctx, namedError) - } else if errors.Is(err, container_model.ErrContainerBlobNotExist) { - apiErrorDefined(ctx, errBlobUnknown) - } else { - switch err { - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + var namedError *Error + switch { + case errors.As(err, &namedError): + apiError(ctx, namedError) + case errors.Is(err, container_model.ErrContainerBlobNotExist): + apiError(ctx, errBlobUnknown) + default: + apiError(ctx, err) } return } @@ -602,9 +585,9 @@ func HeadManifest(ctx *context.Context) { manifest, err := getManifestFromContext(ctx) if err != nil { if err == container_model.ErrContainerBlobNotExist { - apiErrorDefined(ctx, errManifestUnknown) + apiError(ctx, errManifestUnknown) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return } @@ -622,9 +605,9 @@ func GetManifest(ctx *context.Context) { manifest, err := getManifestFromContext(ctx) if err != nil { if err == container_model.ErrContainerBlobNotExist { - apiErrorDefined(ctx, errManifestUnknown) + apiError(ctx, errManifestUnknown) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return } @@ -637,24 +620,24 @@ func GetManifest(ctx *context.Context) { func DeleteManifest(ctx *context.Context) { opts, err := getBlobSearchOptionsFromContext(ctx) if err != nil { - apiErrorDefined(ctx, errManifestUnknown) + apiError(ctx, errManifestUnknown) return } pvs, err := container_model.GetManifestVersions(ctx, opts) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiErrorDefined(ctx, errManifestUnknown) + apiError(ctx, errManifestUnknown) return } for _, pv := range pvs { if err := packages_service.RemovePackageVersion(ctx, ctx.Doer, pv); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } @@ -667,7 +650,7 @@ func DeleteManifest(ctx *context.Context) { func serveBlob(ctx *context.Context, pfd *packages_model.PackageFileDescriptor) { s, u, _, err := packages_service.GetPackageBlobStream(ctx, pfd.File, pfd.Blob) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -700,9 +683,9 @@ func GetTagList(ctx *context.Context) { if _, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.TypeContainer, image); err != nil { if err == packages_model.ErrPackageNotExist { - apiErrorDefined(ctx, errNameUnknown) + apiError(ctx, errNameUnknown) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return } @@ -715,7 +698,7 @@ func GetTagList(ctx *context.Context) { tags, err := container_model.GetImageTags(ctx, ctx.Package.Owner.ID, image, n, last) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } diff --git a/routers/api/packages/container/errors.go b/routers/api/packages/container/errors.go index 1a9b0f32d2fe2..714fa6ce57f3e 100644 --- a/routers/api/packages/container/errors.go +++ b/routers/api/packages/container/errors.go @@ -9,33 +9,37 @@ import ( // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#error-codes var ( - errBlobUnknown = &namedError{Code: "BLOB_UNKNOWN", StatusCode: http.StatusNotFound} - errBlobUploadInvalid = &namedError{Code: "BLOB_UPLOAD_INVALID", StatusCode: http.StatusBadRequest} - errBlobUploadUnknown = &namedError{Code: "BLOB_UPLOAD_UNKNOWN", StatusCode: http.StatusNotFound} - errDigestInvalid = &namedError{Code: "DIGEST_INVALID", StatusCode: http.StatusBadRequest} - errManifestBlobUnknown = &namedError{Code: "MANIFEST_BLOB_UNKNOWN", StatusCode: http.StatusNotFound} - errManifestInvalid = &namedError{Code: "MANIFEST_INVALID", StatusCode: http.StatusBadRequest} - errManifestUnknown = &namedError{Code: "MANIFEST_UNKNOWN", StatusCode: http.StatusNotFound} - errNameInvalid = &namedError{Code: "NAME_INVALID", StatusCode: http.StatusBadRequest} - errNameUnknown = &namedError{Code: "NAME_UNKNOWN", StatusCode: http.StatusNotFound} - errSizeInvalid = &namedError{Code: "SIZE_INVALID", StatusCode: http.StatusBadRequest} - errUnauthorized = &namedError{Code: "UNAUTHORIZED", StatusCode: http.StatusUnauthorized} - errUnsupported = &namedError{Code: "UNSUPPORTED", StatusCode: http.StatusNotImplemented} + errBlobUnknown = &Error{Code: "BLOB_UNKNOWN", StatusCode: http.StatusNotFound} + errBlobUploadInvalid = &Error{Code: "BLOB_UPLOAD_INVALID", StatusCode: http.StatusBadRequest} + errBlobUploadUnknown = &Error{Code: "BLOB_UPLOAD_UNKNOWN", StatusCode: http.StatusNotFound} + errDigestInvalid = &Error{Code: "DIGEST_INVALID", StatusCode: http.StatusBadRequest} + errManifestBlobUnknown = &Error{Code: "MANIFEST_BLOB_UNKNOWN", StatusCode: http.StatusNotFound} + errManifestInvalid = &Error{Code: "MANIFEST_INVALID", StatusCode: http.StatusBadRequest} + errManifestUnknown = &Error{Code: "MANIFEST_UNKNOWN", StatusCode: http.StatusNotFound} + errNameInvalid = &Error{Code: "NAME_INVALID", StatusCode: http.StatusBadRequest} + errNameUnknown = &Error{Code: "NAME_UNKNOWN", StatusCode: http.StatusNotFound} + errSizeInvalid = &Error{Code: "SIZE_INVALID", StatusCode: http.StatusBadRequest} + errUnauthorized = &Error{Code: "UNAUTHORIZED", StatusCode: http.StatusUnauthorized} + errUnsupported = &Error{Code: "UNSUPPORTED", StatusCode: http.StatusNotImplemented} ) -type namedError struct { - Code string +type Errors struct { + Errors []Error `json:"errors"` +} + +type Error struct { + Code string `json:"code"` + Message string `json:"message"` StatusCode int - Message string } -func (e *namedError) Error() string { +func (e *Error) Error() string { return e.Message } // WithMessage creates a new instance of the error with a different message -func (e *namedError) WithMessage(message string) *namedError { - return &namedError{ +func (e *Error) WithMessage(message string) *Error { + return &Error{ Code: e.Code, StatusCode: e.StatusCode, Message: message, @@ -43,8 +47,8 @@ func (e *namedError) WithMessage(message string) *namedError { } // WithStatusCode creates a new instance of the error with a different status code -func (e *namedError) WithStatusCode(statusCode int) *namedError { - return &namedError{ +func (e *Error) WithStatusCode(statusCode int) *Error { + return &Error{ Code: e.Code, StatusCode: statusCode, Message: e.Message, diff --git a/routers/api/packages/cran/cran.go b/routers/api/packages/cran/cran.go index ae43df7c9aa0d..9b9fadeb59b80 100644 --- a/routers/api/packages/cran/cran.go +++ b/routers/api/packages/cran/cran.go @@ -5,7 +5,6 @@ package cran import ( "compress/gzip" - "errors" "fmt" "io" "net/http" @@ -16,12 +15,12 @@ import ( "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" cran_module "code.gitea.io/gitea/modules/packages/cran" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -45,23 +44,23 @@ func EnumerateBinaryPackages(ctx *context.Context) { func enumeratePackages(ctx *context.Context, format string, opts *cran_model.SearchOptions) { if format != "" && format != ".gz" { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } pvs, err := cran_model.SearchLatestVersions(ctx, opts) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -135,7 +134,7 @@ func UploadSourcePackageFile(ctx *context.Context) { func UploadBinaryPackageFile(ctx *context.Context) { platform, rversion := ctx.FormTrim("platform"), ctx.FormTrim("rversion") if platform == "" || rversion == "" { - apiError(ctx, http.StatusBadRequest, nil) + apiError(ctx, nil, http.StatusBadRequest) return } @@ -153,7 +152,7 @@ func UploadBinaryPackageFile(ctx *context.Context) { func uploadPackageFile(ctx *context.Context, compositeKey string, properties map[string]string) { upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } if close { @@ -162,23 +161,19 @@ func uploadPackageFile(ctx *context.Context, compositeKey string, properties map buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() pck, err := cran_module.ParsePackage(buf, buf.Size()) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -207,14 +202,7 @@ func uploadPackageFile(ctx *context.Context, compositeKey string, properties map }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -242,21 +230,13 @@ func DownloadBinaryPackageFile(ctx *context.Context) { func downloadPackageFile(ctx *context.Context, opts *cran_model.SearchOptions) { pf, err := cran_model.SearchFile(ctx, opts) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go index 379137e87eb9c..7427603df7cdc 100644 --- a/routers/api/packages/debian/debian.go +++ b/routers/api/packages/debian/debian.go @@ -5,7 +5,6 @@ package debian import ( stdctx "context" - "errors" "fmt" "io" "net/http" @@ -16,14 +15,14 @@ import ( "code.gitea.io/gitea/modules/context" packages_module "code.gitea.io/gitea/modules/packages" debian_module "code.gitea.io/gitea/modules/packages/debian" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" notify_service "code.gitea.io/gitea/services/notify" packages_service "code.gitea.io/gitea/services/packages" debian_service "code.gitea.io/gitea/services/packages/debian" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -32,7 +31,7 @@ func apiError(ctx *context.Context, status int, obj any) { func GetRepositoryKey(ctx *context.Context) { _, pub, err := debian_service.GetOrCreateKeyPair(ctx, ctx.Package.Owner.ID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -47,7 +46,7 @@ func GetRepositoryKey(ctx *context.Context) { func GetRepositoryFile(ctx *context.Context) { pv, err := debian_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -68,11 +67,7 @@ func GetRepositoryFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -83,7 +78,7 @@ func GetRepositoryFile(ctx *context.Context) { func GetRepositoryFileByHash(ctx *context.Context) { pv, err := debian_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -98,21 +93,17 @@ func GetRepositoryFileByHash(ctx *context.Context) { HashAlgorithm: algorithm, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) != 1 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -123,13 +114,13 @@ func UploadPackageFile(ctx *context.Context) { distribution := strings.TrimSpace(ctx.Params("distribution")) component := strings.TrimSpace(ctx.Params("component")) if distribution == "" || component == "" { - apiError(ctx, http.StatusBadRequest, "invalid distribution or component") + apiError(ctx, "invalid distribution or component", http.StatusBadRequest) return } upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if close { @@ -138,23 +129,19 @@ func UploadPackageFile(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() pck, err := debian_module.ParsePackage(buf) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -187,19 +174,12 @@ func UploadPackageFile(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if err := debian_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, distribution, component, pck.Architecture); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -224,11 +204,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -288,11 +264,7 @@ func DeletePackageFile(ctx *context.Context) { return nil }) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -301,7 +273,7 @@ func DeletePackageFile(ctx *context.Context) { } if err := debian_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, distribution, component, architecture); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index 30854335c0936..abf063ade29af 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -4,7 +4,6 @@ package generic import ( - "errors" "net/http" "regexp" "strings" @@ -13,6 +12,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" packages_module "code.gitea.io/gitea/modules/packages" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" ) @@ -22,7 +22,8 @@ var ( filenameRegex = packageNameRegex ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -43,11 +44,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -61,19 +58,19 @@ func UploadPackage(ctx *context.Context) { filename := ctx.Params("filename") if !packageNameRegex.MatchString(packageName) || !filenameRegex.MatchString(filename) { - apiError(ctx, http.StatusBadRequest, errors.New("Invalid package name or filename")) + apiError(ctx, util.NewInvalidArgumentErrorf("Invalid package name or filename")) return } packageVersion := ctx.Params("packageversion") if packageVersion != strings.TrimSpace(packageVersion) { - apiError(ctx, http.StatusBadRequest, errors.New("Invalid package version")) + apiError(ctx, util.NewInvalidArgumentErrorf("Invalid package version")) return } upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if close { @@ -83,7 +80,7 @@ func UploadPackage(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { log.Error("Error creating hashed buffer: %v", err) - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() @@ -109,14 +106,7 @@ func UploadPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -136,11 +126,7 @@ func DeletePackage(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -163,28 +149,24 @@ func DeletePackageFile(ctx *context.Context) { return pv, pf, nil }() if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pfs, err := packages_model.GetFilesByVersionID(ctx, pv.ID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) == 1 { if err := packages_service.RemovePackageVersion(ctx, ctx.Doer, pv); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } else { if err := packages_service.DeletePackageFile(ctx, pf); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } diff --git a/routers/api/packages/goproxy/goproxy.go b/routers/api/packages/goproxy/goproxy.go index 18e0074ab4d01..8b5935e76b4d6 100644 --- a/routers/api/packages/goproxy/goproxy.go +++ b/routers/api/packages/goproxy/goproxy.go @@ -4,7 +4,6 @@ package goproxy import ( - "errors" "fmt" "io" "net/http" @@ -20,7 +19,8 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -29,11 +29,11 @@ func apiError(ctx *context.Context, status int, obj any) { func EnumeratePackageVersions(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeGo, ctx.Params("name")) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, err, http.StatusNotFound) return } @@ -51,11 +51,7 @@ func EnumeratePackageVersions(ctx *context.Context) { func PackageVersionMetadata(ctx *context.Context) { pv, err := resolvePackage(ctx, ctx.Package.Owner.ID, ctx.Params("name"), ctx.Params("version")) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -71,17 +67,13 @@ func PackageVersionMetadata(ctx *context.Context) { func PackageVersionGoModContent(ctx *context.Context) { pv, err := resolvePackage(ctx, ctx.Package.Owner.ID, ctx.Params("name"), ctx.Params("version")) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } pps, err := packages_model.GetPropertiesByName(ctx, packages_model.PropertyTypeVersion, pv.ID, goproxy_module.PropertyGoMod) if err != nil || len(pps) != 1 { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -91,27 +83,19 @@ func PackageVersionGoModContent(ctx *context.Context) { func DownloadPackageFile(ctx *context.Context) { pv, err := resolvePackage(ctx, ctx.Package.Owner.ID, ctx.Params("name"), ctx.Params("version")) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } pfs, err := packages_model.GetFilesByVersionID(ctx, pv.ID) if err != nil || len(pfs) != 1 { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } s, u, _, err := packages_service.GetPackageFileStream(ctx, pfs[0]) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -155,7 +139,7 @@ func resolvePackage(ctx *context.Context, ownerID int64, name, version string) ( func UploadPackage(ctx *context.Context) { upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if close { @@ -164,23 +148,19 @@ func UploadPackage(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() pck, err := goproxy_module.ParsePackage(buf, buf.Size()) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -208,14 +188,7 @@ func UploadPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go index a8daa69dc3a9d..5069b8e6d033f 100644 --- a/routers/api/packages/helm/helm.go +++ b/routers/api/packages/helm/helm.go @@ -4,7 +4,6 @@ package helm import ( - "errors" "fmt" "io" "net/http" @@ -26,7 +25,8 @@ import ( "gopkg.in/yaml.v3" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { type Error struct { Error string `json:"error"` @@ -45,7 +45,7 @@ func Index(ctx *context.Context) { IsInternal: util.OptionalBoolFalse, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -74,7 +74,7 @@ func Index(ctx *context.Context) { for _, pv := range pvs { metadata := &helm_module.Metadata{} if err := json.Unmarshal([]byte(pv.MetadataJSON), &metadata); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -113,11 +113,11 @@ func DownloadPackageFile(ctx *context.Context) { IsInternal: util.OptionalBoolFalse, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) != 1 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } @@ -129,11 +129,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -144,7 +140,7 @@ func DownloadPackageFile(ctx *context.Context) { func UploadPackage(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if needToClose { @@ -153,23 +149,19 @@ func UploadPackage(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() metadata, err := helm_module.ParseChartArchive(buf) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -197,14 +189,7 @@ func UploadPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } diff --git a/routers/api/packages/helper/helper.go b/routers/api/packages/helper/helper.go index aadb10376c81e..0e200c935373d 100644 --- a/routers/api/packages/helper/helper.go +++ b/routers/api/packages/helper/helper.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" ) // LogAndProcessError logs an error and calls a custom callback with the processed error message. @@ -61,3 +62,14 @@ func ServePackageFile(ctx *context.Context, s io.ReadSeekCloser, u *url.URL, pf ctx.ServeContent(s, opts) } + +// Automatically get HTTP status from error. +func FormResponseCode(obj any, status ...int) int { + if status != nil { + return status[0] + } + if err, ok := obj.(error); ok { + return util.StatusFromError(err) + } + return http.StatusInternalServerError +} diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index 0b93382b01177..622e8cf97640a 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -47,7 +47,8 @@ var ( illegalCharacters = regexp.MustCompile(`[\\/:"<>|?\*]`) ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { // The maven client does not present the error message to the user. Log it for users with access to server logs. if status == http.StatusBadRequest || status == http.StatusInternalServerError { @@ -71,7 +72,7 @@ func ProvidePackageFileHeader(ctx *context.Context) { func handlePackageFile(ctx *context.Context, serveContent bool) { params, err := extractPathParameters(ctx) if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } @@ -88,17 +89,17 @@ func serveMavenMetadata(ctx *context.Context, params parameters) { packageName := params.GroupID + "-" + params.ArtifactID pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, packages_model.ErrPackageNotExist) + apiError(ctx, packages_model.ErrPackageNotExist, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -109,7 +110,7 @@ func serveMavenMetadata(ctx *context.Context, params parameters) { xmlMetadata, err := xml.Marshal(createMetadataResponse(pds)) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } xmlMetadataWithHeader := append([]byte(xml.Header), xmlMetadata...) @@ -151,11 +152,7 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, packageName, params.Version) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -168,17 +165,13 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, filename, packages_model.EmptyFileKey) if err != nil { - if err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } pb, err := packages_model.GetBlobByID(ctx, pf.BlobID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -217,7 +210,7 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool s, u, _, err := packages_service.GetPackageBlobStream(ctx, pf, pb) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -230,7 +223,7 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool func UploadPackageFile(ctx *context.Context) { params, err := extractPathParameters(ctx) if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } @@ -246,7 +239,7 @@ func UploadPackageFile(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() @@ -268,31 +261,23 @@ func UploadPackageFile(ctx *context.Context) { if isChecksumExtension(ext) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvci.Owner.ID, pvci.PackageType, pvci.Name, pvci.Version) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, params.Filename[:len(params.Filename)-len(ext)], packages_model.EmptyFileKey) if err != nil { - if err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pb, err := packages_model.GetBlobByID(ctx, pf.BlobID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } hash, err := io.ReadAll(buf) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -300,7 +285,7 @@ func UploadPackageFile(ctx *context.Context) { (ext == extensionSHA1 && pb.HashSHA1 != string(hash)) || (ext == extensionSHA256 && pb.HashSHA256 != string(hash)) || (ext == extensionSHA512 && pb.HashSHA512 != string(hash)) { - apiError(ctx, http.StatusBadRequest, "hash mismatch") + apiError(ctx, "hash mismatch", http.StatusBadRequest) return } @@ -325,32 +310,32 @@ func UploadPackageFile(ctx *context.Context) { var err error pvci.Metadata, err = maven_module.ParsePackageMetaData(buf) if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } if pvci.Metadata != nil { pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvci.Owner.ID, pvci.PackageType, pvci.Name, pvci.Version) if err != nil && err != packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if pv != nil { raw, err := json.Marshal(pvci.Metadata) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pv.MetadataJSON = string(raw) if err := packages_model.UpdateVersion(ctx, pv); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } @@ -361,14 +346,7 @@ func UploadPackageFile(ctx *context.Context) { pfci, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go index 170edfbe11cc1..9bad2385ecc56 100644 --- a/routers/api/packages/npm/npm.go +++ b/routers/api/packages/npm/npm.go @@ -6,7 +6,6 @@ package npm import ( "bytes" std_ctx "context" - "errors" "fmt" "io" "net/http" @@ -28,10 +27,11 @@ import ( "github.com/hashicorp/go-version" ) -// errInvalidTagName indicates an invalid tag name -var errInvalidTagName = errors.New("The tag name is invalid") +// ErrInvalidTagName indicates an invalid tag name +var ErrInvalidTagName = util.NewInvalidArgumentErrorf("The tag name is invalid") -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, map[string]string{ "error": message, @@ -56,17 +56,17 @@ func PackageMetadata(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeNpm, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, err, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -97,11 +97,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -123,11 +119,11 @@ func DownloadPackageFileByName(ctx *context.Context) { IsInternal: util.OptionalBoolFalse, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) != 1 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } @@ -139,11 +135,7 @@ func DownloadPackageFileByName(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -154,11 +146,7 @@ func DownloadPackageFileByName(ctx *context.Context) { func UploadPackage(ctx *context.Context) { npmPackage, err := npm_module.ParsePackage(ctx.Req.Body) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -169,7 +157,7 @@ func UploadPackage(ctx *context.Context) { if !canWrite { perms, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -177,14 +165,14 @@ func UploadPackage(ctx *context.Context) { } if !canWrite { - apiError(ctx, http.StatusForbidden, "no permission to upload this package") + apiError(ctx, "no permission to upload this package", http.StatusForbidden) return } } buf, err := packages_module.CreateHashedBufferFromReader(bytes.NewReader(npmPackage.Data)) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() @@ -212,31 +200,20 @@ func UploadPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } for _, tag := range npmPackage.DistTags { if err := setPackageTag(ctx, tag, pv, false); err != nil { - if err == errInvalidTagName { - apiError(ctx, http.StatusBadRequest, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } if repo != nil { if err := packages_model.SetRepositoryLink(ctx, pv.PackageID, repo.ID); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } @@ -266,11 +243,7 @@ func DeletePackageVersion(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -283,18 +256,18 @@ func DeletePackage(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeNpm, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, err, http.StatusNotFound) return } for _, pv := range pvs { if err := packages_service.RemovePackageVersion(ctx, ctx.Doer, pv); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } @@ -308,7 +281,7 @@ func ListPackageTags(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeNpm, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -316,7 +289,7 @@ func ListPackageTags(ctx *context.Context) { for _, pv := range pvs { pvps, err := packages_model.GetPropertiesByName(ctx, packages_model.PropertyTypeVersion, pv.ID, npm_module.TagProperty) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } for _, pvp := range pvps { @@ -333,27 +306,19 @@ func AddPackageTag(ctx *context.Context) { body, err := io.ReadAll(ctx.Req.Body) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } version := strings.Trim(string(body), "\"") // is as "version" in the body pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNpm, packageName, version) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if err := setPackageTag(ctx, ctx.Params("tag"), pv, false); err != nil { - if err == errInvalidTagName { - apiError(ctx, http.StatusBadRequest, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } @@ -364,17 +329,13 @@ func DeletePackageTag(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeNpm, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) != 0 { if err := setPackageTag(ctx, ctx.Params("tag"), pvs[0], true); err != nil { - if err == errInvalidTagName { - apiError(ctx, http.StatusBadRequest, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } } @@ -382,11 +343,11 @@ func DeletePackageTag(ctx *context.Context) { func setPackageTag(ctx std_ctx.Context, tag string, pv *packages_model.PackageVersion, deleteOnly bool) error { if tag == "" { - return errInvalidTagName + return ErrInvalidTagName } _, err := version.NewVersion(tag) if err == nil { - return errInvalidTagName + return ErrInvalidTagName } return db.WithTx(ctx, func(ctx std_ctx.Context) error { @@ -442,13 +403,13 @@ func PackageSearch(ctx *context.Context) { ), }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index 769c4c1824571..6533c25c70996 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -27,7 +27,8 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, map[string]string{ "Message": message, @@ -126,13 +127,13 @@ func SearchServiceV2(ctx *context.Context) { Paginator: paginator, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -175,7 +176,7 @@ func SearchServiceV2Count(ctx *context.Context) { IsInternal: util.OptionalBoolFalse, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -194,13 +195,13 @@ func SearchServiceV3(ctx *context.Context) { ), }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -219,17 +220,17 @@ func RegistrationIndex(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, err, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -248,17 +249,13 @@ func RegistrationLeafV2(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -277,17 +274,13 @@ func RegistrationLeafV3(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -317,13 +310,13 @@ func EnumeratePackageVersionsV2(ctx *context.Context) { Paginator: paginator, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -361,7 +354,7 @@ func EnumeratePackageVersionsV2Count(ctx *context.Context) { IsInternal: util.OptionalBoolFalse, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -374,11 +367,11 @@ func EnumeratePackageVersionsV3(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, err, http.StatusNotFound) return } @@ -406,11 +399,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -453,14 +442,7 @@ func UploadPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -482,17 +464,13 @@ func UploadSymbolPackage(ctx *context.Context) { pdbs, err := nuget_module.ExtractPortablePdb(buf, buf.Size()) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } defer pdbs.Close() if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -516,16 +494,7 @@ func UploadSymbolPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrPackageNotExist: - apiError(ctx, http.StatusNotFound, err) - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -547,14 +516,7 @@ func UploadSymbolPackage(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } } @@ -567,7 +529,7 @@ func processUploadedFile(ctx *context.Context, expectedType nuget_module.Package upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return nil, nil, closables } @@ -577,7 +539,7 @@ func processUploadedFile(ctx *context.Context, expectedType nuget_module.Package buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return nil, nil, closables } closables = append(closables, buf) @@ -585,18 +547,18 @@ func processUploadedFile(ctx *context.Context, expectedType nuget_module.Package np, err := nuget_module.ParsePackageMetaData(buf, buf.Size()) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) } else { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } return nil, nil, closables } if np.PackageType != expectedType { - apiError(ctx, http.StatusBadRequest, errors.New("unexpected package type")) + apiError(ctx, errors.New("unexpected package type"), http.StatusBadRequest) return nil, nil, closables } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return nil, nil, closables } return np, buf, closables @@ -609,7 +571,7 @@ func DownloadSymbolFile(ctx *context.Context) { filename2 := ctx.Params("filename2") if filename != filename2 { - apiError(ctx, http.StatusBadRequest, nil) + apiError(ctx, nil, http.StatusBadRequest) return } @@ -622,21 +584,17 @@ func DownloadSymbolFile(ctx *context.Context) { }, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pfs) != 1 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -660,11 +618,7 @@ func DeletePackage(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } ctx.Status(http.StatusNoContent) diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go index 1f605c6c9f432..5fd589864ea9d 100644 --- a/routers/api/packages/pub/pub.go +++ b/routers/api/packages/pub/pub.go @@ -4,7 +4,6 @@ package pub import ( - "errors" "fmt" "io" "net/http" @@ -20,7 +19,6 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" pub_module "code.gitea.io/gitea/modules/packages/pub" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" packages_service "code.gitea.io/gitea/services/packages" ) @@ -34,7 +32,8 @@ func jsonResponse(ctx *context.Context, status int, obj any) { } } -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) type Error struct { Code string `json:"code"` Message string `json:"message"` @@ -85,17 +84,17 @@ func EnumeratePackageVersions(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, err, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -124,17 +123,13 @@ func PackageVersionMetadata(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -161,30 +156,26 @@ func RequestUpload(ctx *context.Context) { func UploadPackageFile(ctx *context.Context) { file, _, err := ctx.Req.FormFile("file") if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } defer file.Close() buf, err := packages_module.CreateHashedBufferFromReader(file) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() pck, err := pub_module.ParsePackage(buf) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -211,14 +202,7 @@ func UploadPackageFile(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -233,11 +217,7 @@ func FinalizePackage(ctx *context.Context) { _, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -258,17 +238,13 @@ func DownloadPackageFile(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -276,7 +252,7 @@ func DownloadPackageFile(ctx *context.Context) { s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go index 5718b1203b48b..daa4d3122cc77 100644 --- a/routers/api/packages/pypi/pypi.go +++ b/routers/api/packages/pypi/pypi.go @@ -37,7 +37,8 @@ var versionMatcher = regexp.MustCompile(`\Av?` + `(?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)?` + // local version `\z`) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -49,17 +50,17 @@ func PackageMetadata(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypePyPI, packageName) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, err, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -93,11 +94,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -108,14 +105,14 @@ func DownloadPackageFile(ctx *context.Context) { func UploadPackageFile(ctx *context.Context) { file, fileHeader, err := ctx.Req.FormFile("content") if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } defer file.Close() buf, err := packages_module.CreateHashedBufferFromReader(file) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() @@ -123,19 +120,19 @@ func UploadPackageFile(ctx *context.Context) { _, _, hashSHA256, _ := buf.Sums() if !strings.EqualFold(ctx.Req.FormValue("sha256_digest"), hex.EncodeToString(hashSHA256)) { - apiError(ctx, http.StatusBadRequest, "hash mismatch") + apiError(ctx, "hash mismatch", http.StatusBadRequest) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } packageName := normalizer.Replace(ctx.Req.FormValue("name")) packageVersion := ctx.Req.FormValue("version") if !isValidNameAndVersion(packageName, packageVersion) { - apiError(ctx, http.StatusBadRequest, "invalid name or version") + apiError(ctx, "invalid name or version", http.StatusBadRequest) return } @@ -175,14 +172,7 @@ func UploadPackageFile(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go index f5d8b67e16d93..e2929afa05520 100644 --- a/routers/api/packages/rpm/rpm.go +++ b/routers/api/packages/rpm/rpm.go @@ -5,7 +5,6 @@ package rpm import ( stdctx "context" - "errors" "fmt" "io" "net/http" @@ -18,14 +17,14 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" rpm_module "code.gitea.io/gitea/modules/packages/rpm" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" notify_service "code.gitea.io/gitea/services/notify" packages_service "code.gitea.io/gitea/services/packages" rpm_service "code.gitea.io/gitea/services/packages/rpm" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -47,7 +46,7 @@ gpgkey=`+url+`/repository.key`) func GetRepositoryKey(ctx *context.Context) { _, pub, err := rpm_service.GetOrCreateKeyPair(ctx, ctx.Package.Owner.ID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -61,7 +60,7 @@ func GetRepositoryKey(ctx *context.Context) { func GetRepositoryFile(ctx *context.Context) { pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -73,11 +72,7 @@ func GetRepositoryFile(ctx *context.Context) { }, ) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -87,7 +82,7 @@ func GetRepositoryFile(ctx *context.Context) { func UploadPackageFile(ctx *context.Context) { upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if close { @@ -96,29 +91,25 @@ func UploadPackageFile(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() pck, err := rpm_module.ParsePackage(buf) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } fileMetadataRaw, err := json.Marshal(pck.FileMetadata) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -147,19 +138,12 @@ func UploadPackageFile(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if err := rpm_service.BuildRepositoryFiles(ctx, ctx.Package.Owner.ID); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -183,11 +167,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -239,11 +219,7 @@ func DeletePackageFile(webctx *context.Context) { return nil }) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(webctx, http.StatusNotFound, err) - } else { - apiError(webctx, http.StatusInternalServerError, err) - } + apiError(webctx, err) return } @@ -252,7 +228,7 @@ func DeletePackageFile(webctx *context.Context) { } if err := rpm_service.BuildRepositoryFiles(webctx, webctx.Package.Owner.ID); err != nil { - apiError(webctx, http.StatusInternalServerError, err) + apiError(webctx, err) return } diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go index 01fd4dad66915..148c9258e30ab 100644 --- a/routers/api/packages/rubygems/rubygems.go +++ b/routers/api/packages/rubygems/rubygems.go @@ -6,7 +6,6 @@ package rubygems import ( "compress/gzip" "compress/zlib" - "errors" "fmt" "io" "net/http" @@ -21,7 +20,8 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -31,7 +31,7 @@ func apiError(ctx *context.Context, status int, obj any) { func EnumeratePackages(ctx *context.Context) { packages, err := packages_model.GetVersionsByPackageType(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -46,7 +46,7 @@ func EnumeratePackagesLatest(ctx *context.Context) { IsInternal: util.OptionalBoolFalse, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -61,7 +61,7 @@ func EnumeratePackagesPreRelease(ctx *context.Context) { func enumeratePackages(ctx *context.Context, filename string, pvs []*packages_model.PackageVersion) { pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -96,24 +96,24 @@ func ServePackageSpecification(ctx *context.Context) { filename := ctx.Params("filename") if !strings.HasSuffix(filename, ".gemspec.rz") { - apiError(ctx, http.StatusNotImplemented, nil) + apiError(ctx, nil, http.StatusNotImplemented) return } pvs, err := getVersionsByFilename(ctx, filename[:len(filename)-10]+"gem") if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) != 1 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } pd, err := packages_model.GetPackageDescriptor(ctx, pvs[0]) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -166,12 +166,12 @@ func DownloadPackageFile(ctx *context.Context) { pvs, err := getVersionsByFilename(ctx, filename) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) != 1 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } @@ -183,11 +183,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -198,7 +194,7 @@ func DownloadPackageFile(ctx *context.Context) { func UploadPackageFile(ctx *context.Context) { upload, close, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err) return } if close { @@ -207,22 +203,18 @@ func UploadPackageFile(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() rp, err := rubygems_module.ParsePackageMetaData(buf) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -256,14 +248,7 @@ func UploadPackageFile(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -274,7 +259,7 @@ func UploadPackageFile(ctx *context.Context) { func DeletePackage(ctx *context.Context) { // Go populates the form only for POST, PUT and PATCH requests if err := ctx.Req.ParseMultipartForm(32 << 20); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } packageName := ctx.FormString("gem_name") @@ -291,11 +276,7 @@ func DeletePackage(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) } } diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index 427e262d0633c..13cff499e2fbd 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -4,7 +4,6 @@ package swift import ( - "errors" "fmt" "io" "net/http" @@ -69,7 +68,8 @@ func setResponseHeaders(resp http.ResponseWriter, h *headers) { } // https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#33-error-handling -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) // https://www.rfc-editor.org/rfc/rfc7807 type Problem struct { Status int `json:"status"` @@ -95,7 +95,7 @@ func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context return func(ctx *context.Context) { accept := ctx.Req.Header.Get("Accept") if accept != "" && accept != requiredAcceptHeader { - apiError(ctx, http.StatusBadRequest, fmt.Sprintf("Unexpected accept header. Should be '%s'.", requiredAcceptHeader)) + apiError(ctx, fmt.Sprintf("Unexpected accept header. Should be '%s'.", requiredAcceptHeader), http.StatusBadRequest) } } } @@ -119,17 +119,17 @@ func EnumeratePackageVersions(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(packageScope, packageName)) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -175,17 +175,13 @@ func PackageVersionMetadata(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, id, ctx.Params("version")) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -235,17 +231,13 @@ func DownloadManifest(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(packageScope, packageName), packageVersion) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -287,7 +279,7 @@ func UploadPackageFile(ctx *context.Context) { v, err := version.NewVersion(ctx.Params("version")) if !scopePattern.MatchString(packageScope) || !namePattern.MatchString(packageName) || err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } @@ -295,14 +287,14 @@ func UploadPackageFile(ctx *context.Context) { file, _, err := ctx.Req.FormFile("source-archive") if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } defer file.Close() buf, err := packages_module.CreateHashedBufferFromReader(file) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() @@ -315,16 +307,12 @@ func UploadPackageFile(ctx *context.Context) { pck, err := swift_module.ParsePackage(buf, buf.Size(), mr) if err != nil { - if errors.Is(err, util.ErrInvalidArgument) { - apiError(ctx, http.StatusBadRequest, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -355,14 +343,7 @@ func UploadPackageFile(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -382,17 +363,13 @@ func UploadPackageFile(ctx *context.Context) { func DownloadPackageFile(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(ctx.Params("scope"), ctx.Params("name")), ctx.Params("version")) if err != nil { - if errors.Is(err, util.ErrNotExist) { - apiError(ctx, http.StatusNotFound, err) - } else { - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } pd, err := packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -400,7 +377,7 @@ func DownloadPackageFile(ctx *context.Context) { s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -423,7 +400,7 @@ type LookupPackageIdentifiersResponse struct { func LookupPackageIdentifiers(ctx *context.Context) { url := ctx.FormTrim("url") if url == "" { - apiError(ctx, http.StatusBadRequest, nil) + apiError(ctx, nil, http.StatusBadRequest) return } @@ -436,18 +413,18 @@ func LookupPackageIdentifiers(ctx *context.Context) { IsInternal: util.OptionalBoolFalse, }) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, nil) + apiError(ctx, nil, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } diff --git a/routers/api/packages/vagrant/vagrant.go b/routers/api/packages/vagrant/vagrant.go index af9cd08a6297e..7cddf872ad231 100644 --- a/routers/api/packages/vagrant/vagrant.go +++ b/routers/api/packages/vagrant/vagrant.go @@ -22,7 +22,8 @@ import ( "github.com/hashicorp/go-version" ) -func apiError(ctx *context.Context, status int, obj any) { +func apiError(ctx *context.Context, obj any, statuses ...int) { + status := helper.FormResponseCode(obj, statuses...) helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, struct { Errors []string `json:"errors"` @@ -36,7 +37,7 @@ func apiError(ctx *context.Context, status int, obj any) { func CheckAuthenticate(ctx *context.Context) { if ctx.Doer == nil { - apiError(ctx, http.StatusUnauthorized, "Invalid access token") + apiError(ctx, "Invalid access token", http.StatusUnauthorized) return } @@ -46,11 +47,11 @@ func CheckAuthenticate(ctx *context.Context) { func CheckBoxAvailable(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeVagrant, ctx.Params("name")) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, nil, http.StatusNotFound) return } @@ -103,17 +104,17 @@ func packageDescriptorToMetadata(baseURL string, pd *packages_model.PackageDescr func EnumeratePackageVersions(ctx *context.Context) { pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeVagrant, ctx.Params("name")) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if len(pvs) == 0 { - apiError(ctx, http.StatusNotFound, err) + apiError(ctx, nil, http.StatusNotFound) return } pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -140,18 +141,18 @@ func UploadPackageFile(ctx *context.Context) { boxVersion := ctx.Params("version") _, err := version.NewSemver(boxVersion) if err != nil { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } boxProvider := ctx.Params("provider") if !strings.HasSuffix(boxProvider, ".box") { - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, err, http.StatusBadRequest) return } upload, needsClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if needsClose { @@ -160,19 +161,19 @@ func UploadPackageFile(ctx *context.Context) { buf, err := packages_module.CreateHashedBufferFromReader(upload) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } defer buf.Close() metadata, err := vagrant_module.ParseMetadataFromBox(buf) if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } if _, err := buf.Seek(0, io.SeekStart); err != nil { - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } @@ -202,14 +203,7 @@ func UploadPackageFile(ctx *context.Context) { }, ) if err != nil { - switch err { - case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusConflict, err) - case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: - apiError(ctx, http.StatusForbidden, err) - default: - apiError(ctx, http.StatusInternalServerError, err) - } + apiError(ctx, err) return } @@ -230,11 +224,7 @@ func DownloadPackageFile(ctx *context.Context) { }, ) if err != nil { - if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { - apiError(ctx, http.StatusNotFound, err) - return - } - apiError(ctx, http.StatusInternalServerError, err) + apiError(ctx, err) return } diff --git a/services/packages/packages.go b/services/packages/packages.go index 56d5cc04de2df..bc045361b90cd 100644 --- a/services/packages/packages.go +++ b/services/packages/packages.go @@ -26,9 +26,9 @@ import ( ) var ( - ErrQuotaTypeSize = errors.New("maximum allowed package type size exceeded") - ErrQuotaTotalSize = errors.New("maximum allowed package storage quota exceeded") - ErrQuotaTotalCount = errors.New("maximum allowed package count exceeded") + ErrQuotaTypeSize = util.NewPayloadTooLargeErrorf("maximum allowed package type size exceeded") + ErrQuotaTotalSize = util.NewLimitExceededErrorf("maximum allowed package storage quota exceeded") + ErrQuotaTotalCount = util.NewLimitExceededErrorf("maximum allowed package count exceeded") ) // PackageInfo describes a package diff --git a/tests/integration/api_packages_test.go b/tests/integration/api_packages_test.go index e530b2c1ad79d..85e8d8824f108 100644 --- a/tests/integration/api_packages_test.go +++ b/tests/integration/api_packages_test.go @@ -402,17 +402,17 @@ func TestPackageQuota(t *testing.T) { } setting.Packages.LimitTotalOwnerCount = 0 - uploadPackage(user, "1.0", http.StatusForbidden) + uploadPackage(user, "1.0", http.StatusConflict) uploadPackage(admin, "1.0", http.StatusCreated) setting.Packages.LimitTotalOwnerCount = limitTotalOwnerCount setting.Packages.LimitTotalOwnerSize = 0 - uploadPackage(user, "1.1", http.StatusForbidden) + uploadPackage(user, "1.1", http.StatusConflict) uploadPackage(admin, "1.1", http.StatusCreated) setting.Packages.LimitTotalOwnerSize = limitTotalOwnerSize setting.Packages.LimitSizeGeneric = 0 - uploadPackage(user, "1.2", http.StatusForbidden) + uploadPackage(user, "1.2", http.StatusRequestEntityTooLarge) uploadPackage(admin, "1.2", http.StatusCreated) setting.Packages.LimitSizeGeneric = limitSizeGeneric }) @@ -430,12 +430,12 @@ func TestPackageQuota(t *testing.T) { } setting.Packages.LimitTotalOwnerSize = 0 - uploadBlob(user, "2", http.StatusForbidden) + uploadBlob(user, "2", http.StatusConflict) uploadBlob(admin, "2", http.StatusCreated) setting.Packages.LimitTotalOwnerSize = limitTotalOwnerSize setting.Packages.LimitSizeContainer = 0 - uploadBlob(user, "3", http.StatusForbidden) + uploadBlob(user, "3", http.StatusRequestEntityTooLarge) uploadBlob(admin, "3", http.StatusCreated) setting.Packages.LimitSizeContainer = limitSizeContainer })