1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-15 23:17:19 +00:00

Refactor error system (#33610)

This commit is contained in:
wxiaoguang
2025-02-17 14:13:17 +08:00
committed by GitHub
parent 69de5a65c2
commit f35850f48e
184 changed files with 2100 additions and 2106 deletions

View File

@@ -171,7 +171,7 @@ func Search(ctx *context.APIContext) {
opts.Collaborate = optional.Some(true)
case "":
default:
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid search mode: \"%s\"", mode))
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid search mode: \"%s\"", mode))
return
}
@@ -193,11 +193,11 @@ func Search(ctx *context.APIContext) {
if orderBy, ok := searchModeMap[sortMode]; ok {
opts.OrderBy = orderBy
} else {
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid sort mode: \"%s\"", sortMode))
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort mode: \"%s\"", sortMode))
return
}
} else {
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid sort order: \"%s\"", sortOrder))
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort order: \"%s\"", sortOrder))
return
}
}
@@ -245,7 +245,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre
// If the readme template does not exist, a 400 will be returned.
if opt.AutoInit && len(opt.Readme) > 0 && !slices.Contains(repo_module.Readmes, opt.Readme) {
ctx.Error(http.StatusBadRequest, "", fmt.Errorf("readme template does not exist, available templates: %v", repo_module.Readmes))
ctx.APIError(http.StatusBadRequest, fmt.Errorf("readme template does not exist, available templates: %v", repo_module.Readmes))
return
}
@@ -265,13 +265,13 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre
})
if err != nil {
if repo_model.IsErrRepoAlreadyExist(err) {
ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.")
ctx.APIError(http.StatusConflict, "The repository with the same name already exists.")
} else if db.IsErrNameReserved(err) ||
db.IsErrNamePatternNotAllowed(err) ||
label.IsErrTemplateLoad(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
ctx.APIError(http.StatusUnprocessableEntity, err)
} else {
ctx.Error(http.StatusInternalServerError, "CreateRepository", err)
ctx.APIError(http.StatusInternalServerError, err)
}
return
}
@@ -279,7 +279,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre
// reload repo from db to get a real state after creation
repo, err = repo_model.GetRepositoryByID(ctx, repo.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetRepositoryByID", err)
ctx.APIError(http.StatusInternalServerError, err)
}
ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeOwner}))
@@ -311,7 +311,7 @@ func Create(ctx *context.APIContext) {
opt := web.GetForm(ctx).(*api.CreateRepoOption)
if ctx.Doer.IsOrganization() {
// Shouldn't reach this condition, but just in case.
ctx.Error(http.StatusUnprocessableEntity, "", "not allowed creating repository for organization")
ctx.APIError(http.StatusUnprocessableEntity, "not allowed creating repository for organization")
return
}
CreateUserRepo(ctx, ctx.Doer, *opt)
@@ -355,12 +355,12 @@ func Generate(ctx *context.APIContext) {
form := web.GetForm(ctx).(*api.GenerateRepoOption)
if !ctx.Repo.Repository.IsTemplate {
ctx.Error(http.StatusUnprocessableEntity, "", "this is not a template repo")
ctx.APIError(http.StatusUnprocessableEntity, "this is not a template repo")
return
}
if ctx.Doer.IsOrganization() {
ctx.Error(http.StatusUnprocessableEntity, "", "not allowed creating repository for organization")
ctx.APIError(http.StatusUnprocessableEntity, "not allowed creating repository for organization")
return
}
@@ -379,7 +379,7 @@ func Generate(ctx *context.APIContext) {
}
if !opts.IsValid() {
ctx.Error(http.StatusUnprocessableEntity, "", "must select at least one template item")
ctx.APIError(http.StatusUnprocessableEntity, "must select at least one template item")
return
}
@@ -395,22 +395,22 @@ func Generate(ctx *context.APIContext) {
return
}
ctx.Error(http.StatusInternalServerError, "GetUserByName", err)
ctx.APIError(http.StatusInternalServerError, err)
return
}
if !ctx.Doer.IsAdmin && !ctxUser.IsOrganization() {
ctx.Error(http.StatusForbidden, "", "Only admin can generate repository for other user.")
ctx.APIError(http.StatusForbidden, "Only admin can generate repository for other user.")
return
}
if !ctx.Doer.IsAdmin {
canCreate, err := organization.OrgFromUser(ctxUser).CanCreateOrgRepo(ctx, ctx.Doer.ID)
if err != nil {
ctx.ServerError("CanCreateOrgRepo", err)
ctx.APIErrorInternal(err)
return
} else if !canCreate {
ctx.Error(http.StatusForbidden, "", "Given user is not allowed to create repository in organization.")
ctx.APIError(http.StatusForbidden, "Given user is not allowed to create repository in organization.")
return
}
}
@@ -419,12 +419,12 @@ func Generate(ctx *context.APIContext) {
repo, err := repo_service.GenerateRepository(ctx, ctx.Doer, ctxUser, ctx.Repo.Repository, opts)
if err != nil {
if repo_model.IsErrRepoAlreadyExist(err) {
ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.")
ctx.APIError(http.StatusConflict, "The repository with the same name already exists.")
} else if db.IsErrNameReserved(err) ||
db.IsErrNamePatternNotAllowed(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
ctx.APIError(http.StatusUnprocessableEntity, err)
} else {
ctx.Error(http.StatusInternalServerError, "CreateRepository", err)
ctx.APIError(http.StatusInternalServerError, err)
}
return
}
@@ -498,25 +498,25 @@ func CreateOrgRepo(ctx *context.APIContext) {
org, err := organization.GetOrgByName(ctx, ctx.PathParam("org"))
if err != nil {
if organization.IsErrOrgNotExist(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
ctx.APIError(http.StatusUnprocessableEntity, err)
} else {
ctx.Error(http.StatusInternalServerError, "GetOrgByName", err)
ctx.APIError(http.StatusInternalServerError, err)
}
return
}
if !organization.HasOrgOrUserVisible(ctx, org.AsUser(), ctx.Doer) {
ctx.NotFound("HasOrgOrUserVisible", nil)
ctx.APIErrorNotFound("HasOrgOrUserVisible", nil)
return
}
if !ctx.Doer.IsAdmin {
canCreate, err := org.CanCreateOrgRepo(ctx, ctx.Doer.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CanCreateOrgRepo", err)
ctx.APIError(http.StatusInternalServerError, err)
return
} else if !canCreate {
ctx.Error(http.StatusForbidden, "", "Given user is not allowed to create repository in organization.")
ctx.APIError(http.StatusForbidden, "Given user is not allowed to create repository in organization.")
return
}
}
@@ -548,7 +548,7 @@ func Get(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
if err := ctx.Repo.Repository.LoadAttributes(ctx); err != nil {
ctx.Error(http.StatusInternalServerError, "Repository.LoadAttributes", err)
ctx.APIError(http.StatusInternalServerError, err)
return
}
@@ -578,19 +578,19 @@ func GetByID(ctx *context.APIContext) {
repo, err := repo_model.GetRepositoryByID(ctx, ctx.PathParamInt64("id"))
if err != nil {
if repo_model.IsErrRepoNotExist(err) {
ctx.NotFound()
ctx.APIErrorNotFound()
} else {
ctx.Error(http.StatusInternalServerError, "GetRepositoryByID", err)
ctx.APIError(http.StatusInternalServerError, err)
}
return
}
permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)
ctx.APIError(http.StatusInternalServerError, err)
return
} else if !permission.HasAnyUnitAccess() {
ctx.NotFound()
ctx.APIErrorNotFound()
return
}
ctx.JSON(http.StatusOK, convert.ToRepo(ctx, repo, permission))
@@ -653,7 +653,7 @@ func Edit(ctx *context.APIContext) {
repo, err := repo_model.GetRepositoryByID(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.InternalServerError(err)
ctx.APIErrorInternal(err)
return
}
@@ -673,13 +673,13 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
if err := repo_service.ChangeRepositoryName(ctx, ctx.Doer, repo, newRepoName); err != nil {
switch {
case repo_model.IsErrRepoAlreadyExist(err):
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is already taken [name: %s]", newRepoName), err)
ctx.APIError(http.StatusUnprocessableEntity, err)
case db.IsErrNameReserved(err):
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is reserved [name: %s]", newRepoName), err)
ctx.APIError(http.StatusUnprocessableEntity, err)
case db.IsErrNamePatternNotAllowed(err):
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name's pattern is not allowed [name: %s, pattern: %s]", newRepoName, err.(db.ErrNamePatternNotAllowed).Pattern), err)
ctx.APIError(http.StatusUnprocessableEntity, err)
default:
ctx.Error(http.StatusUnprocessableEntity, "ChangeRepositoryName", err)
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("ChangeRepositoryName: %w", err))
}
return err
}
@@ -703,7 +703,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
// Visibility of forked repository is forced sync with base repository.
if repo.IsFork {
if err := repo.GetBaseRepo(ctx); err != nil {
ctx.Error(http.StatusInternalServerError, "Unable to load base repository", err)
ctx.APIError(http.StatusInternalServerError, err)
return err
}
*opts.Private = repo.BaseRepo.IsPrivate
@@ -713,7 +713,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
// when ForcePrivate enabled, you could change public repo to private, but only admin users can change private to public
if visibilityChanged && setting.Repository.ForcePrivate && !*opts.Private && !ctx.Doer.IsAdmin {
err := fmt.Errorf("cannot change private repository to public")
ctx.Error(http.StatusUnprocessableEntity, "Force Private enabled", err)
ctx.APIError(http.StatusUnprocessableEntity, err)
return err
}
@@ -728,7 +728,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
var err error
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, repo)
if err != nil {
ctx.Error(http.StatusInternalServerError, "Unable to OpenRepository", err)
ctx.APIError(http.StatusInternalServerError, err)
return err
}
}
@@ -738,7 +738,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
if opts.DefaultBranch != nil && repo.DefaultBranch != *opts.DefaultBranch && (repo.IsEmpty || ctx.Repo.GitRepo.IsBranchExist(*opts.DefaultBranch)) {
if !repo.IsEmpty {
if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, *opts.DefaultBranch); err != nil {
ctx.Error(http.StatusInternalServerError, "SetDefaultBranch", err)
ctx.APIError(http.StatusInternalServerError, err)
return err
}
updateRepoLicense = true
@@ -747,7 +747,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
}
if err := repo_service.UpdateRepository(ctx, repo, visibilityChanged); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateRepository", err)
ctx.APIError(http.StatusInternalServerError, err)
return err
}
@@ -755,7 +755,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
if err := repo_service.AddRepoToLicenseUpdaterQueue(&repo_service.LicenseUpdaterOptions{
RepoID: ctx.Repo.Repository.ID,
}); err != nil {
ctx.Error(http.StatusInternalServerError, "AddRepoToLicenseUpdaterQueue", err)
ctx.APIError(http.StatusInternalServerError, err)
return err
}
}
@@ -782,12 +782,12 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
// Check that values are valid
if !validation.IsValidExternalURL(opts.ExternalTracker.ExternalTrackerURL) {
err := fmt.Errorf("External tracker URL not valid")
ctx.Error(http.StatusUnprocessableEntity, "Invalid external tracker URL", err)
ctx.APIError(http.StatusUnprocessableEntity, err)
return err
}
if len(opts.ExternalTracker.ExternalTrackerFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(opts.ExternalTracker.ExternalTrackerFormat) {
err := fmt.Errorf("External tracker URL format not valid")
ctx.Error(http.StatusUnprocessableEntity, "Invalid external tracker URL format", err)
ctx.APIError(http.StatusUnprocessableEntity, err)
return err
}
@@ -849,7 +849,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
// Check that values are valid
if !validation.IsValidExternalURL(opts.ExternalWiki.ExternalWikiURL) {
err := fmt.Errorf("External wiki URL not valid")
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid external wiki URL")
ctx.APIError(http.StatusUnprocessableEntity, "Invalid external wiki URL")
return err
}
@@ -1024,7 +1024,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
if len(units)+len(deleteUnitTypes) > 0 {
if err := repo_service.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateRepositoryUnits", err)
ctx.APIError(http.StatusInternalServerError, err)
return err
}
}
@@ -1040,13 +1040,13 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e
if opts.Archived != nil {
if repo.IsMirror {
err := fmt.Errorf("repo is a mirror, cannot archive/un-archive")
ctx.Error(http.StatusUnprocessableEntity, err.Error(), err)
ctx.APIError(http.StatusUnprocessableEntity, err)
return err
}
if *opts.Archived {
if err := repo_model.SetArchiveRepoState(ctx, repo, *opts.Archived); err != nil {
log.Error("Tried to archive a repo: %s", err)
ctx.Error(http.StatusInternalServerError, "ArchiveRepoState", err)
ctx.APIError(http.StatusInternalServerError, err)
return err
}
if err := actions_model.CleanRepoScheduleTasks(ctx, repo); err != nil {
@@ -1056,7 +1056,7 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e
} else {
if err := repo_model.SetArchiveRepoState(ctx, repo, *opts.Archived); err != nil {
log.Error("Tried to un-archive a repo: %s", err)
ctx.Error(http.StatusInternalServerError, "ArchiveRepoState", err)
ctx.APIError(http.StatusInternalServerError, err)
return err
}
if ctx.Repo.Repository.UnitEnabled(ctx, unit_model.TypeActions) {
@@ -1084,7 +1084,7 @@ func updateMirror(ctx *context.APIContext, opts api.EditRepoOption) error {
mirror, err := repo_model.GetMirrorByRepoID(ctx, repo.ID)
if err != nil {
log.Error("Failed to get mirror: %s", err)
ctx.Error(http.StatusInternalServerError, "MirrorInterval", err)
ctx.APIError(http.StatusInternalServerError, err)
return err
}
@@ -1094,14 +1094,14 @@ func updateMirror(ctx *context.APIContext, opts api.EditRepoOption) error {
interval, err := time.ParseDuration(*opts.MirrorInterval)
if err != nil {
log.Error("Wrong format for MirrorInternal Sent: %s", err)
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
ctx.APIError(http.StatusUnprocessableEntity, err)
return err
}
// Ensure the provided duration is not too short
if interval != 0 && interval < setting.Mirror.MinInterval {
err := fmt.Errorf("invalid mirror interval: %s is below minimum interval: %s", interval, setting.Mirror.MinInterval)
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
ctx.APIError(http.StatusUnprocessableEntity, err)
return err
}
@@ -1120,7 +1120,7 @@ func updateMirror(ctx *context.APIContext, opts api.EditRepoOption) error {
// finally update the mirror in the DB
if err := repo_model.UpdateMirror(ctx, mirror); err != nil {
log.Error("Failed to Set Mirror Interval: %s", err)
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
ctx.APIError(http.StatusUnprocessableEntity, err)
return err
}
@@ -1158,10 +1158,10 @@ func Delete(ctx *context.APIContext) {
canDelete, err := repo_module.CanUserDelete(ctx, repo, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CanUserDelete", err)
ctx.APIError(http.StatusInternalServerError, err)
return
} else if !canDelete {
ctx.Error(http.StatusForbidden, "", "Given user is not owner of organization.")
ctx.APIError(http.StatusForbidden, "Given user is not owner of organization.")
return
}
@@ -1170,7 +1170,7 @@ func Delete(ctx *context.APIContext) {
}
if err := repo_service.DeleteRepository(ctx, ctx.Doer, repo, true); err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteRepository", err)
ctx.APIError(http.StatusInternalServerError, err)
return
}
@@ -1315,7 +1315,7 @@ func ListRepoActivityFeeds(ctx *context.APIContext) {
feeds, count, err := feed_service.GetFeeds(ctx, opts)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetFeeds", err)
ctx.APIError(http.StatusInternalServerError, err)
return
}
ctx.SetTotalCountHeader(count)