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:
@@ -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)
|
||||
|
Reference in New Issue
Block a user