Skip to content

Commit df87091

Browse files
committed
Move all errors to their own sub packages
1 parent 824fac3 commit df87091

38 files changed

+606
-658
lines changed

models/error.go

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

models/repo/repo.go

Lines changed: 1 addition & 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

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/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: 9 additions & 9 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) || files_service.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) ||
894894
files_service.IsErrFilenameInvalid(err) ||
895-
models.IsErrSHADoesNotMatch(err) ||
896-
models.IsErrCommitIDDoesNotMatch(err) ||
897-
models.IsErrSHAOrCommitIDNotProvided(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")

routers/api/v1/repo/patch.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import (
77
"net/http"
88
"time"
99

10-
"code.gitea.io/gitea/models"
1110
git_model "code.gitea.io/gitea/models/git"
1211
repo_model "code.gitea.io/gitea/models/repo"
1312
"code.gitea.io/gitea/modules/git"
1413
api "code.gitea.io/gitea/modules/structs"
1514
"code.gitea.io/gitea/modules/web"
1615
"code.gitea.io/gitea/services/context"
16+
pull_service "code.gitea.io/gitea/services/pull"
1717
"code.gitea.io/gitea/services/repository/files"
1818
)
1919

@@ -92,12 +92,12 @@ func ApplyDiffPatch(ctx *context.APIContext) {
9292

9393
fileResponse, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, opts)
9494
if err != nil {
95-
if models.IsErrUserCannotCommit(err) || models.IsErrFilePathProtected(err) {
95+
if files.IsErrUserCannotCommit(err) || pull_service.IsErrFilePathProtected(err) {
9696
ctx.Error(http.StatusForbidden, "Access", err)
9797
return
9898
}
99-
if git_model.IsErrBranchAlreadyExists(err) || files.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
100-
models.IsErrFilePathInvalid(err) || models.IsErrRepoFileAlreadyExists(err) {
99+
if git_model.IsErrBranchAlreadyExists(err) || files.IsErrFilenameInvalid(err) || pull_service.IsErrSHADoesNotMatch(err) ||
100+
files.IsErrFilePathInvalid(err) || files.IsErrRepoFileAlreadyExists(err) {
101101
ctx.Error(http.StatusUnprocessableEntity, "Invalid", err)
102102
return
103103
}

routers/api/v1/repo/pull.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"strings"
1313
"time"
1414

15-
"code.gitea.io/gitea/models"
1615
activities_model "code.gitea.io/gitea/models/activities"
1716
git_model "code.gitea.io/gitea/models/git"
1817
issues_model "code.gitea.io/gitea/models/issues"
@@ -765,7 +764,7 @@ func EditPullRequest(ctx *context.APIContext) {
765764
} else if issues_model.IsErrIssueIsClosed(err) {
766765
ctx.Error(http.StatusUnprocessableEntity, "IsErrIssueIsClosed", err)
767766
return
768-
} else if models.IsErrPullRequestHasMerged(err) {
767+
} else if pull_service.IsErrPullRequestHasMerged(err) {
769768
ctx.Error(http.StatusConflict, "IsErrPullRequestHasMerged", err)
770769
return
771770
}
@@ -941,7 +940,7 @@ func MergePullRequest(ctx *context.APIContext) {
941940
ctx.Error(http.StatusMethodNotAllowed, "PR is a work in progress", "Work in progress PRs cannot be merged")
942941
} else if errors.Is(err, pull_service.ErrNotMergeableState) {
943942
ctx.Error(http.StatusMethodNotAllowed, "PR not in mergeable state", "Please try again later")
944-
} else if models.IsErrDisallowedToMerge(err) {
943+
} else if pull_service.IsErrDisallowedToMerge(err) {
945944
ctx.Error(http.StatusMethodNotAllowed, "PR is not ready to be merged", err)
946945
} else if asymkey_service.IsErrWontSign(err) {
947946
ctx.Error(http.StatusMethodNotAllowed, fmt.Sprintf("Protected branch %s requires signed commits but this merge would not be signed", pr.BaseBranch), err)
@@ -954,7 +953,7 @@ func MergePullRequest(ctx *context.APIContext) {
954953
// handle manually-merged mark
955954
if manuallyMerged {
956955
if err := pull_service.MergedManually(ctx, pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil {
957-
if models.IsErrInvalidMergeStyle(err) {
956+
if pull_service.IsErrInvalidMergeStyle(err) {
958957
ctx.Error(http.StatusMethodNotAllowed, "Invalid merge style", fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do)))
959958
return
960959
}
@@ -1004,20 +1003,20 @@ func MergePullRequest(ctx *context.APIContext) {
10041003
}
10051004

10061005
if err := pull_service.Merge(ctx, pr, ctx.Doer, ctx.Repo.GitRepo, repo_model.MergeStyle(form.Do), form.HeadCommitID, message, false); err != nil {
1007-
if models.IsErrInvalidMergeStyle(err) {
1006+
if pull_service.IsErrInvalidMergeStyle(err) {
10081007
ctx.Error(http.StatusMethodNotAllowed, "Invalid merge style", fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do)))
1009-
} else if models.IsErrMergeConflicts(err) {
1010-
conflictError := err.(models.ErrMergeConflicts)
1008+
} else if pull_service.IsErrMergeConflicts(err) {
1009+
conflictError := err.(pull_service.ErrMergeConflicts)
10111010
ctx.JSON(http.StatusConflict, conflictError)
1012-
} else if models.IsErrRebaseConflicts(err) {
1013-
conflictError := err.(models.ErrRebaseConflicts)
1011+
} else if pull_service.IsErrRebaseConflicts(err) {
1012+
conflictError := err.(pull_service.ErrRebaseConflicts)
10141013
ctx.JSON(http.StatusConflict, conflictError)
1015-
} else if models.IsErrMergeUnrelatedHistories(err) {
1016-
conflictError := err.(models.ErrMergeUnrelatedHistories)
1014+
} else if pull_service.IsErrMergeUnrelatedHistories(err) {
1015+
conflictError := err.(pull_service.ErrMergeUnrelatedHistories)
10171016
ctx.JSON(http.StatusConflict, conflictError)
10181017
} else if git.IsErrPushOutOfDate(err) {
10191018
ctx.Error(http.StatusConflict, "Merge", "merge push out of date")
1020-
} else if models.IsErrSHADoesNotMatch(err) {
1019+
} else if pull_service.IsErrSHADoesNotMatch(err) {
10211020
ctx.Error(http.StatusConflict, "Merge", "head out of date")
10221021
} else if git.IsErrPushRejected(err) {
10231022
errPushRej := err.(*git.ErrPushRejected)
@@ -1308,10 +1307,10 @@ func UpdatePullRequest(ctx *context.APIContext) {
13081307
message := fmt.Sprintf("Merge branch '%s' into %s", pr.BaseBranch, pr.HeadBranch)
13091308

13101309
if err = pull_service.Update(ctx, pr, ctx.Doer, message, rebase); err != nil {
1311-
if models.IsErrMergeConflicts(err) {
1310+
if pull_service.IsErrMergeConflicts(err) {
13121311
ctx.Error(http.StatusConflict, "Update", "merge failed because of conflict")
13131312
return
1314-
} else if models.IsErrRebaseConflicts(err) {
1313+
} else if pull_service.IsErrRebaseConflicts(err) {
13151314
ctx.Error(http.StatusConflict, "Update", "rebase failed because of conflict")
13161315
return
13171316
}

routers/api/v1/repo/release.go

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

10-
"code.gitea.io/gitea/models"
1110
"code.gitea.io/gitea/models/db"
1211
"code.gitea.io/gitea/models/perm"
1312
repo_model "code.gitea.io/gitea/models/repo"
@@ -250,7 +249,7 @@ func CreateRelease(ctx *context.APIContext) {
250249
if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil {
251250
if repo_model.IsErrReleaseAlreadyExist(err) {
252251
ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err)
253-
} else if models.IsErrProtectedTagName(err) {
252+
} else if release_service.IsErrProtectedTagName(err) {
254253
ctx.Error(http.StatusUnprocessableEntity, "ProtectedTagName", err)
255254
} else if git.IsErrNotExist(err) {
256255
ctx.Error(http.StatusNotFound, "ErrNotExist", fmt.Errorf("target \"%v\" not found: %w", rel.Target, err))
@@ -408,7 +407,7 @@ func DeleteRelease(ctx *context.APIContext) {
408407
return
409408
}
410409
if err := release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, rel, ctx.Doer, false); err != nil {
411-
if models.IsErrProtectedTagName(err) {
410+
if release_service.IsErrProtectedTagName(err) {
412411
ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag")
413412
return
414413
}

0 commit comments

Comments
 (0)