Skip to content

Commit 751fe8b

Browse files
authored
Move some errors to their own sub packages (#32880)
1 parent 4774151 commit 751fe8b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+728
-781
lines changed

models/error.go

Lines changed: 0 additions & 510 deletions
This file was deleted.

models/organization/org_user.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,21 @@ func init() {
3636
db.RegisterModel(new(OrgUser))
3737
}
3838

39+
// ErrUserHasOrgs represents a "UserHasOrgs" kind of error.
40+
type ErrUserHasOrgs struct {
41+
UID int64
42+
}
43+
44+
// IsErrUserHasOrgs checks if an error is a ErrUserHasOrgs.
45+
func IsErrUserHasOrgs(err error) bool {
46+
_, ok := err.(ErrUserHasOrgs)
47+
return ok
48+
}
49+
50+
func (err ErrUserHasOrgs) Error() string {
51+
return fmt.Sprintf("user still has membership of organizations [uid: %d]", err.UID)
52+
}
53+
3954
// GetOrganizationCount returns count of membership of organization of the user.
4055
func GetOrganizationCount(ctx context.Context, u *user_model.User) (int64, error) {
4156
return db.GetEngine(ctx).

models/packages/package.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,21 @@ func FindUnreferencedPackages(ctx context.Context) ([]*Package, error) {
301301
Find(&ps)
302302
}
303303

304+
// ErrUserOwnPackages notifies that the user (still) owns the packages.
305+
type ErrUserOwnPackages struct {
306+
UID int64
307+
}
308+
309+
// IsErrUserOwnPackages checks if an error is an ErrUserOwnPackages.
310+
func IsErrUserOwnPackages(err error) bool {
311+
_, ok := err.(ErrUserOwnPackages)
312+
return ok
313+
}
314+
315+
func (err ErrUserOwnPackages) Error() string {
316+
return fmt.Sprintf("user still has ownership of packages [uid: %d]", err.UID)
317+
}
318+
304319
// HasOwnerPackages tests if a user/org has accessible packages
305320
func HasOwnerPackages(ctx context.Context, ownerID int64) (bool, error) {
306321
return db.GetEngine(ctx).

models/repo/repo.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type ErrUserDoesNotHaveAccessToRepo struct {
3737
RepoName string
3838
}
3939

40-
// IsErrUserDoesNotHaveAccessToRepo checks if an error is a ErrRepoFileAlreadyExists.
40+
// IsErrUserDoesNotHaveAccessToRepo checks if an error is a ErrUserDoesNotHaveAccessToRepo.
4141
func IsErrUserDoesNotHaveAccessToRepo(err error) bool {
4242
_, ok := err.(ErrUserDoesNotHaveAccessToRepo)
4343
return ok
@@ -866,6 +866,21 @@ func (repo *Repository) TemplateRepo(ctx context.Context) *Repository {
866866
return repo
867867
}
868868

869+
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
870+
type ErrUserOwnRepos struct {
871+
UID int64
872+
}
873+
874+
// IsErrUserOwnRepos checks if an error is a ErrUserOwnRepos.
875+
func IsErrUserOwnRepos(err error) bool {
876+
_, ok := err.(ErrUserOwnRepos)
877+
return ok
878+
}
879+
880+
func (err ErrUserOwnRepos) Error() string {
881+
return fmt.Sprintf("user still has ownership of repositories [uid: %d]", err.UID)
882+
}
883+
869884
type CountRepositoryOptions struct {
870885
OwnerID int64
871886
Private optional.Option[bool]

models/user/user.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,21 @@ func createUser(ctx context.Context, u *User, meta *Meta, createdByAdmin bool, o
788788
return committer.Commit()
789789
}
790790

791+
// ErrDeleteLastAdminUser represents a "DeleteLastAdminUser" kind of error.
792+
type ErrDeleteLastAdminUser struct {
793+
UID int64
794+
}
795+
796+
// IsErrDeleteLastAdminUser checks if an error is a ErrDeleteLastAdminUser.
797+
func IsErrDeleteLastAdminUser(err error) bool {
798+
_, ok := err.(ErrDeleteLastAdminUser)
799+
return ok
800+
}
801+
802+
func (err ErrDeleteLastAdminUser) Error() string {
803+
return fmt.Sprintf("can not delete the last admin user [uid: %d]", err.UID)
804+
}
805+
791806
// IsLastAdminUser check whether user is the last admin
792807
func IsLastAdminUser(ctx context.Context, user *User) bool {
793808
if user.IsAdmin && CountUsers(ctx, &CountUserFilter{IsAdmin: optional.Some(true)}) <= 1 {

modules/git/remote.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ package git
55

66
import (
77
"context"
8+
"fmt"
9+
"net/url"
10+
"strings"
811

912
giturl "code.gitea.io/gitea/modules/git/url"
13+
"code.gitea.io/gitea/modules/util"
1014
)
1115

1216
// GetRemoteAddress returns remote url of git repository in the repoPath with special remote name
@@ -37,3 +41,61 @@ func GetRemoteURL(ctx context.Context, repoPath, remoteName string) (*giturl.Git
3741
}
3842
return giturl.Parse(addr)
3943
}
44+
45+
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
46+
type ErrInvalidCloneAddr struct {
47+
Host string
48+
IsURLError bool
49+
IsInvalidPath bool
50+
IsProtocolInvalid bool
51+
IsPermissionDenied bool
52+
LocalPath bool
53+
}
54+
55+
// IsErrInvalidCloneAddr checks if an error is a ErrInvalidCloneAddr.
56+
func IsErrInvalidCloneAddr(err error) bool {
57+
_, ok := err.(*ErrInvalidCloneAddr)
58+
return ok
59+
}
60+
61+
func (err *ErrInvalidCloneAddr) Error() string {
62+
if err.IsInvalidPath {
63+
return fmt.Sprintf("migration/cloning from '%s' is not allowed: the provided path is invalid", err.Host)
64+
}
65+
if err.IsProtocolInvalid {
66+
return fmt.Sprintf("migration/cloning from '%s' is not allowed: the provided url protocol is not allowed", err.Host)
67+
}
68+
if err.IsPermissionDenied {
69+
return fmt.Sprintf("migration/cloning from '%s' is not allowed.", err.Host)
70+
}
71+
if err.IsURLError {
72+
return fmt.Sprintf("migration/cloning from '%s' is not allowed: the provided url is invalid", err.Host)
73+
}
74+
75+
return fmt.Sprintf("migration/cloning from '%s' is not allowed", err.Host)
76+
}
77+
78+
func (err *ErrInvalidCloneAddr) Unwrap() error {
79+
return util.ErrInvalidArgument
80+
}
81+
82+
// ParseRemoteAddr checks if given remote address is valid,
83+
// and returns composed URL with needed username and password.
84+
func ParseRemoteAddr(remoteAddr, authUsername, authPassword string) (string, error) {
85+
remoteAddr = strings.TrimSpace(remoteAddr)
86+
// Remote address can be HTTP/HTTPS/Git URL or local path.
87+
if strings.HasPrefix(remoteAddr, "http://") ||
88+
strings.HasPrefix(remoteAddr, "https://") ||
89+
strings.HasPrefix(remoteAddr, "git://") {
90+
u, err := url.Parse(remoteAddr)
91+
if err != nil {
92+
return "", &ErrInvalidCloneAddr{IsURLError: true, Host: remoteAddr}
93+
}
94+
if len(authUsername)+len(authPassword) > 0 {
95+
u.User = url.UserPassword(authUsername, authPassword)
96+
}
97+
remoteAddr = u.String()
98+
}
99+
100+
return remoteAddr, nil
101+
}

routers/api/v1/admin/user.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import (
99
"fmt"
1010
"net/http"
1111

12-
"code.gitea.io/gitea/models"
1312
asymkey_model "code.gitea.io/gitea/models/asymkey"
1413
"code.gitea.io/gitea/models/auth"
1514
"code.gitea.io/gitea/models/db"
15+
org_model "code.gitea.io/gitea/models/organization"
16+
packages_model "code.gitea.io/gitea/models/packages"
17+
repo_model "code.gitea.io/gitea/models/repo"
1618
user_model "code.gitea.io/gitea/models/user"
1719
"code.gitea.io/gitea/modules/auth/password"
1820
"code.gitea.io/gitea/modules/log"
@@ -247,7 +249,7 @@ func EditUser(ctx *context.APIContext) {
247249
}
248250

249251
if err := user_service.UpdateUser(ctx, ctx.ContextUser, opts); err != nil {
250-
if models.IsErrDeleteLastAdminUser(err) {
252+
if user_model.IsErrDeleteLastAdminUser(err) {
251253
ctx.Error(http.StatusBadRequest, "LastAdmin", err)
252254
} else {
253255
ctx.Error(http.StatusInternalServerError, "UpdateUser", err)
@@ -299,10 +301,10 @@ func DeleteUser(ctx *context.APIContext) {
299301
}
300302

301303
if err := user_service.DeleteUser(ctx, ctx.ContextUser, ctx.FormBool("purge")); err != nil {
302-
if models.IsErrUserOwnRepos(err) ||
303-
models.IsErrUserHasOrgs(err) ||
304-
models.IsErrUserOwnPackages(err) ||
305-
models.IsErrDeleteLastAdminUser(err) {
304+
if repo_model.IsErrUserOwnRepos(err) ||
305+
org_model.IsErrUserHasOrgs(err) ||
306+
packages_model.IsErrUserOwnPackages(err) ||
307+
user_model.IsErrDeleteLastAdminUser(err) {
306308
ctx.Error(http.StatusUnprocessableEntity, "", err)
307309
} else {
308310
ctx.Error(http.StatusInternalServerError, "DeleteUser", err)

routers/api/v1/repo/branch.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"fmt"
1010
"net/http"
1111

12-
"code.gitea.io/gitea/models"
1312
"code.gitea.io/gitea/models/db"
1413
git_model "code.gitea.io/gitea/models/git"
1514
"code.gitea.io/gitea/models/organization"
@@ -24,6 +23,7 @@ import (
2423
"code.gitea.io/gitea/services/context"
2524
"code.gitea.io/gitea/services/convert"
2625
pull_service "code.gitea.io/gitea/services/pull"
26+
release_service "code.gitea.io/gitea/services/release"
2727
repo_service "code.gitea.io/gitea/services/repository"
2828
)
2929

@@ -247,7 +247,7 @@ func CreateBranch(ctx *context.APIContext) {
247247
if err != nil {
248248
if git_model.IsErrBranchNotExist(err) {
249249
ctx.Error(http.StatusNotFound, "", "The old branch does not exist")
250-
} else if models.IsErrTagAlreadyExists(err) {
250+
} else if release_service.IsErrTagAlreadyExists(err) {
251251
ctx.Error(http.StatusConflict, "", "The branch with the same tag already exists.")
252252
} else if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
253253
ctx.Error(http.StatusConflict, "", "The branch already exists.")

routers/api/v1/repo/file.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"strings"
1616
"time"
1717

18-
"code.gitea.io/gitea/models"
1918
git_model "code.gitea.io/gitea/models/git"
2019
repo_model "code.gitea.io/gitea/models/repo"
2120
"code.gitea.io/gitea/models/unit"
@@ -30,6 +29,7 @@ import (
3029
"code.gitea.io/gitea/modules/web"
3130
"code.gitea.io/gitea/routers/common"
3231
"code.gitea.io/gitea/services/context"
32+
pull_service "code.gitea.io/gitea/services/pull"
3333
archiver_service "code.gitea.io/gitea/services/repository/archiver"
3434
files_service "code.gitea.io/gitea/services/repository/files"
3535
)
@@ -736,12 +736,12 @@ func UpdateFile(ctx *context.APIContext) {
736736
}
737737

738738
func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) {
739-
if models.IsErrUserCannotCommit(err) || models.IsErrFilePathProtected(err) {
739+
if files_service.IsErrUserCannotCommit(err) || pull_service.IsErrFilePathProtected(err) {
740740
ctx.Error(http.StatusForbidden, "Access", err)
741741
return
742742
}
743-
if git_model.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
744-
models.IsErrFilePathInvalid(err) || models.IsErrRepoFileAlreadyExists(err) {
743+
if git_model.IsErrBranchAlreadyExists(err) || files_service.IsErrFilenameInvalid(err) || pull_service.IsErrSHADoesNotMatch(err) ||
744+
files_service.IsErrFilePathInvalid(err) || files_service.IsErrRepoFileAlreadyExists(err) {
745745
ctx.Error(http.StatusUnprocessableEntity, "Invalid", err)
746746
return
747747
}
@@ -887,17 +887,17 @@ func DeleteFile(ctx *context.APIContext) {
887887
}
888888

889889
if filesResponse, err := files_service.ChangeRepoFiles(ctx, ctx.Repo.Repository, ctx.Doer, opts); err != nil {
890-
if git.IsErrBranchNotExist(err) || models.IsErrRepoFileDoesNotExist(err) || git.IsErrNotExist(err) {
890+
if git.IsErrBranchNotExist(err) || files_service.IsErrRepoFileDoesNotExist(err) || git.IsErrNotExist(err) {
891891
ctx.Error(http.StatusNotFound, "DeleteFile", err)
892892
return
893893
} else if git_model.IsErrBranchAlreadyExists(err) ||
894-
models.IsErrFilenameInvalid(err) ||
895-
models.IsErrSHADoesNotMatch(err) ||
896-
models.IsErrCommitIDDoesNotMatch(err) ||
897-
models.IsErrSHAOrCommitIDNotProvided(err) {
894+
files_service.IsErrFilenameInvalid(err) ||
895+
pull_service.IsErrSHADoesNotMatch(err) ||
896+
files_service.IsErrCommitIDDoesNotMatch(err) ||
897+
files_service.IsErrSHAOrCommitIDNotProvided(err) {
898898
ctx.Error(http.StatusBadRequest, "DeleteFile", err)
899899
return
900-
} else if models.IsErrUserCannotCommit(err) {
900+
} else if files_service.IsErrUserCannotCommit(err) {
901901
ctx.Error(http.StatusForbidden, "DeleteFile", err)
902902
return
903903
}

routers/api/v1/repo/migrate.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import (
1010
"net/http"
1111
"strings"
1212

13-
"code.gitea.io/gitea/models"
1413
"code.gitea.io/gitea/models/db"
1514
"code.gitea.io/gitea/models/organization"
1615
"code.gitea.io/gitea/models/perm"
1716
access_model "code.gitea.io/gitea/models/perm/access"
1817
repo_model "code.gitea.io/gitea/models/repo"
1918
user_model "code.gitea.io/gitea/models/user"
19+
"code.gitea.io/gitea/modules/git"
2020
"code.gitea.io/gitea/modules/graceful"
2121
"code.gitea.io/gitea/modules/lfs"
2222
"code.gitea.io/gitea/modules/log"
@@ -27,7 +27,6 @@ import (
2727
"code.gitea.io/gitea/modules/web"
2828
"code.gitea.io/gitea/services/context"
2929
"code.gitea.io/gitea/services/convert"
30-
"code.gitea.io/gitea/services/forms"
3130
"code.gitea.io/gitea/services/migrations"
3231
notify_service "code.gitea.io/gitea/services/notify"
3332
repo_service "code.gitea.io/gitea/services/repository"
@@ -104,7 +103,7 @@ func Migrate(ctx *context.APIContext) {
104103
}
105104
}
106105

107-
remoteAddr, err := forms.ParseRemoteAddr(form.CloneAddr, form.AuthUsername, form.AuthPassword)
106+
remoteAddr, err := git.ParseRemoteAddr(form.CloneAddr, form.AuthUsername, form.AuthPassword)
108107
if err == nil {
109108
err = migrations.IsMigrateURLAllowed(remoteAddr, ctx.Doer)
110109
}
@@ -237,7 +236,7 @@ func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, err
237236
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("The username '%s' contains invalid characters.", err.(db.ErrNameCharsNotAllowed).Name))
238237
case db.IsErrNamePatternNotAllowed(err):
239238
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("The pattern '%s' is not allowed in a username.", err.(db.ErrNamePatternNotAllowed).Pattern))
240-
case models.IsErrInvalidCloneAddr(err):
239+
case git.IsErrInvalidCloneAddr(err):
241240
ctx.Error(http.StatusUnprocessableEntity, "", err)
242241
case base.IsErrNotSupported(err):
243242
ctx.Error(http.StatusUnprocessableEntity, "", err)
@@ -256,8 +255,8 @@ func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, err
256255
}
257256

258257
func handleRemoteAddrError(ctx *context.APIContext, err error) {
259-
if models.IsErrInvalidCloneAddr(err) {
260-
addrErr := err.(*models.ErrInvalidCloneAddr)
258+
if git.IsErrInvalidCloneAddr(err) {
259+
addrErr := err.(*git.ErrInvalidCloneAddr)
261260
switch {
262261
case addrErr.IsURLError:
263262
ctx.Error(http.StatusUnprocessableEntity, "", err)

routers/api/v1/repo/mirror.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@ import (
99
"net/http"
1010
"time"
1111

12-
"code.gitea.io/gitea/models"
1312
"code.gitea.io/gitea/models/db"
1413
repo_model "code.gitea.io/gitea/models/repo"
1514
"code.gitea.io/gitea/models/unit"
15+
"code.gitea.io/gitea/modules/git"
1616
"code.gitea.io/gitea/modules/setting"
1717
api "code.gitea.io/gitea/modules/structs"
1818
"code.gitea.io/gitea/modules/util"
1919
"code.gitea.io/gitea/modules/web"
2020
"code.gitea.io/gitea/routers/api/v1/utils"
2121
"code.gitea.io/gitea/services/context"
2222
"code.gitea.io/gitea/services/convert"
23-
"code.gitea.io/gitea/services/forms"
2423
"code.gitea.io/gitea/services/migrations"
2524
mirror_service "code.gitea.io/gitea/services/mirror"
2625
)
@@ -344,7 +343,7 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro
344343
return
345344
}
346345

347-
address, err := forms.ParseRemoteAddr(mirrorOption.RemoteAddress, mirrorOption.RemoteUsername, mirrorOption.RemotePassword)
346+
address, err := git.ParseRemoteAddr(mirrorOption.RemoteAddress, mirrorOption.RemoteUsername, mirrorOption.RemotePassword)
348347
if err == nil {
349348
err = migrations.IsMigrateURLAllowed(address, ctx.ContextUser)
350349
}
@@ -397,8 +396,8 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro
397396
}
398397

399398
func HandleRemoteAddressError(ctx *context.APIContext, err error) {
400-
if models.IsErrInvalidCloneAddr(err) {
401-
addrErr := err.(*models.ErrInvalidCloneAddr)
399+
if git.IsErrInvalidCloneAddr(err) {
400+
addrErr := err.(*git.ErrInvalidCloneAddr)
402401
switch {
403402
case addrErr.IsProtocolInvalid:
404403
ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Invalid mirror protocol")

0 commit comments

Comments
 (0)