Skip to content

Commit f29b101

Browse files
6543Yohann Delafollye
authored and
Yohann Delafollye
committed
Handle expected errors in FileCreate & FileUpdate API (go-gitea#11643)
as title needed for go-gitea#11641
1 parent 192940f commit f29b101

File tree

4 files changed

+57
-4
lines changed

4 files changed

+57
-4
lines changed

integrations/api_repo_file_create_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ func TestAPICreateFile(t *testing.T) {
189189
treePath = "README.md"
190190
url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
191191
req = NewRequestWithJSON(t, "POST", url, &createFileOptions)
192-
resp = session.MakeRequest(t, req, http.StatusInternalServerError)
192+
resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity)
193193
expectedAPIError := context.APIError{
194194
Message: "repository file already exists [path: " + treePath + "]",
195195
URL: setting.API.SwaggerURL,

integrations/api_repo_file_update_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ func TestAPIUpdateFile(t *testing.T) {
208208
updateFileOptions.SHA = "badsha"
209209
url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
210210
req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions)
211-
resp = session.MakeRequest(t, req, http.StatusInternalServerError)
211+
resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity)
212212
expectedAPIError := context.APIError{
213213
Message: "sha does not match [given: " + updateFileOptions.SHA + ", expected: " + correctSHA + "]",
214214
URL: setting.API.SwaggerURL,

routers/api/v1/repo/file.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package repo
77

88
import (
99
"encoding/base64"
10+
"fmt"
1011
"net/http"
1112
"time"
1213

@@ -198,6 +199,16 @@ func CreateFile(ctx *context.APIContext, apiOpts api.CreateFileOptions) {
198199
// responses:
199200
// "201":
200201
// "$ref": "#/responses/FileResponse"
202+
// "403":
203+
// "$ref": "#/responses/error"
204+
// "404":
205+
// "$ref": "#/responses/notFound"
206+
// "422":
207+
// "$ref": "#/responses/error"
208+
209+
if ctx.Repo.Repository.IsEmpty {
210+
ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
211+
}
201212

202213
if apiOpts.BranchName == "" {
203214
apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
@@ -235,7 +246,7 @@ func CreateFile(ctx *context.APIContext, apiOpts api.CreateFileOptions) {
235246
}
236247

237248
if fileResponse, err := createOrUpdateFile(ctx, opts); err != nil {
238-
ctx.Error(http.StatusInternalServerError, "CreateFile", err)
249+
handleCreateOrUpdateFileError(ctx, err)
239250
} else {
240251
ctx.JSON(http.StatusCreated, fileResponse)
241252
}
@@ -274,6 +285,16 @@ func UpdateFile(ctx *context.APIContext, apiOpts api.UpdateFileOptions) {
274285
// responses:
275286
// "200":
276287
// "$ref": "#/responses/FileResponse"
288+
// "403":
289+
// "$ref": "#/responses/error"
290+
// "404":
291+
// "$ref": "#/responses/notFound"
292+
// "422":
293+
// "$ref": "#/responses/error"
294+
295+
if ctx.Repo.Repository.IsEmpty {
296+
ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
297+
}
277298

278299
if apiOpts.BranchName == "" {
279300
apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
@@ -313,12 +334,26 @@ func UpdateFile(ctx *context.APIContext, apiOpts api.UpdateFileOptions) {
313334
}
314335

315336
if fileResponse, err := createOrUpdateFile(ctx, opts); err != nil {
316-
ctx.Error(http.StatusInternalServerError, "UpdateFile", err)
337+
handleCreateOrUpdateFileError(ctx, err)
317338
} else {
318339
ctx.JSON(http.StatusOK, fileResponse)
319340
}
320341
}
321342

343+
func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) {
344+
if models.IsErrUserCannotCommit(err) || models.IsErrFilePathProtected(err) {
345+
ctx.Error(http.StatusForbidden, "Access", err)
346+
return
347+
}
348+
if models.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
349+
models.IsErrFilePathInvalid(err) || models.IsErrRepoFileAlreadyExists(err) {
350+
ctx.Error(http.StatusUnprocessableEntity, "Invalid", err)
351+
return
352+
}
353+
354+
ctx.Error(http.StatusInternalServerError, "UpdateFile", err)
355+
}
356+
322357
// Called from both CreateFile or UpdateFile to handle both
323358
func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileOptions) (*api.FileResponse, error) {
324359
if !canWriteFiles(ctx.Repo) {

templates/swagger/v1_json.tmpl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,6 +2793,15 @@
27932793
"responses": {
27942794
"200": {
27952795
"$ref": "#/responses/FileResponse"
2796+
},
2797+
"403": {
2798+
"$ref": "#/responses/error"
2799+
},
2800+
"404": {
2801+
"$ref": "#/responses/notFound"
2802+
},
2803+
"422": {
2804+
"$ref": "#/responses/error"
27962805
}
27972806
}
27982807
},
@@ -2842,6 +2851,15 @@
28422851
"responses": {
28432852
"201": {
28442853
"$ref": "#/responses/FileResponse"
2854+
},
2855+
"403": {
2856+
"$ref": "#/responses/error"
2857+
},
2858+
"404": {
2859+
"$ref": "#/responses/notFound"
2860+
},
2861+
"422": {
2862+
"$ref": "#/responses/error"
28452863
}
28462864
}
28472865
},

0 commit comments

Comments
 (0)