mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 05:25:15 +01:00 
			
		
		
		
	Handle expected errors in FileCreate & FileUpdate API (#11643)
as title needed for #11641
This commit is contained in:
		
							parent
							
								
									34b6983f56
								
							
						
					
					
						commit
						b636cd6fd4
					
				@ -189,7 +189,7 @@ func TestAPICreateFile(t *testing.T) {
 | 
				
			|||||||
		treePath = "README.md"
 | 
							treePath = "README.md"
 | 
				
			||||||
		url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
 | 
				
			||||||
		req = NewRequestWithJSON(t, "POST", url, &createFileOptions)
 | 
							req = NewRequestWithJSON(t, "POST", url, &createFileOptions)
 | 
				
			||||||
		resp = session.MakeRequest(t, req, http.StatusInternalServerError)
 | 
							resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity)
 | 
				
			||||||
		expectedAPIError := context.APIError{
 | 
							expectedAPIError := context.APIError{
 | 
				
			||||||
			Message: "repository file already exists [path: " + treePath + "]",
 | 
								Message: "repository file already exists [path: " + treePath + "]",
 | 
				
			||||||
			URL:     setting.API.SwaggerURL,
 | 
								URL:     setting.API.SwaggerURL,
 | 
				
			||||||
 | 
				
			|||||||
@ -208,7 +208,7 @@ func TestAPIUpdateFile(t *testing.T) {
 | 
				
			|||||||
		updateFileOptions.SHA = "badsha"
 | 
							updateFileOptions.SHA = "badsha"
 | 
				
			||||||
		url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
 | 
							url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
 | 
				
			||||||
		req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions)
 | 
							req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions)
 | 
				
			||||||
		resp = session.MakeRequest(t, req, http.StatusInternalServerError)
 | 
							resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity)
 | 
				
			||||||
		expectedAPIError := context.APIError{
 | 
							expectedAPIError := context.APIError{
 | 
				
			||||||
			Message: "sha does not match [given: " + updateFileOptions.SHA + ", expected: " + correctSHA + "]",
 | 
								Message: "sha does not match [given: " + updateFileOptions.SHA + ", expected: " + correctSHA + "]",
 | 
				
			||||||
			URL:     setting.API.SwaggerURL,
 | 
								URL:     setting.API.SwaggerURL,
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@ package repo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/base64"
 | 
						"encoding/base64"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -198,6 +199,16 @@ func CreateFile(ctx *context.APIContext, apiOpts api.CreateFileOptions) {
 | 
				
			|||||||
	// responses:
 | 
						// responses:
 | 
				
			||||||
	//   "201":
 | 
						//   "201":
 | 
				
			||||||
	//     "$ref": "#/responses/FileResponse"
 | 
						//     "$ref": "#/responses/FileResponse"
 | 
				
			||||||
 | 
						//   "403":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/error"
 | 
				
			||||||
 | 
						//   "404":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/notFound"
 | 
				
			||||||
 | 
						//   "422":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/error"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ctx.Repo.Repository.IsEmpty {
 | 
				
			||||||
 | 
							ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if apiOpts.BranchName == "" {
 | 
						if apiOpts.BranchName == "" {
 | 
				
			||||||
		apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
 | 
							apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
 | 
				
			||||||
@ -235,7 +246,7 @@ func CreateFile(ctx *context.APIContext, apiOpts api.CreateFileOptions) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if fileResponse, err := createOrUpdateFile(ctx, opts); err != nil {
 | 
						if fileResponse, err := createOrUpdateFile(ctx, opts); err != nil {
 | 
				
			||||||
		ctx.Error(http.StatusInternalServerError, "CreateFile", err)
 | 
							handleCreateOrUpdateFileError(ctx, err)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ctx.JSON(http.StatusCreated, fileResponse)
 | 
							ctx.JSON(http.StatusCreated, fileResponse)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -274,6 +285,16 @@ func UpdateFile(ctx *context.APIContext, apiOpts api.UpdateFileOptions) {
 | 
				
			|||||||
	// responses:
 | 
						// responses:
 | 
				
			||||||
	//   "200":
 | 
						//   "200":
 | 
				
			||||||
	//     "$ref": "#/responses/FileResponse"
 | 
						//     "$ref": "#/responses/FileResponse"
 | 
				
			||||||
 | 
						//   "403":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/error"
 | 
				
			||||||
 | 
						//   "404":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/notFound"
 | 
				
			||||||
 | 
						//   "422":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/error"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ctx.Repo.Repository.IsEmpty {
 | 
				
			||||||
 | 
							ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if apiOpts.BranchName == "" {
 | 
						if apiOpts.BranchName == "" {
 | 
				
			||||||
		apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
 | 
							apiOpts.BranchName = ctx.Repo.Repository.DefaultBranch
 | 
				
			||||||
@ -313,12 +334,26 @@ func UpdateFile(ctx *context.APIContext, apiOpts api.UpdateFileOptions) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if fileResponse, err := createOrUpdateFile(ctx, opts); err != nil {
 | 
						if fileResponse, err := createOrUpdateFile(ctx, opts); err != nil {
 | 
				
			||||||
		ctx.Error(http.StatusInternalServerError, "UpdateFile", err)
 | 
							handleCreateOrUpdateFileError(ctx, err)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ctx.JSON(http.StatusOK, fileResponse)
 | 
							ctx.JSON(http.StatusOK, fileResponse)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) {
 | 
				
			||||||
 | 
						if models.IsErrUserCannotCommit(err) || models.IsErrFilePathProtected(err) {
 | 
				
			||||||
 | 
							ctx.Error(http.StatusForbidden, "Access", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if models.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
 | 
				
			||||||
 | 
							models.IsErrFilePathInvalid(err) || models.IsErrRepoFileAlreadyExists(err) {
 | 
				
			||||||
 | 
							ctx.Error(http.StatusUnprocessableEntity, "Invalid", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.Error(http.StatusInternalServerError, "UpdateFile", err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Called from both CreateFile or UpdateFile to handle both
 | 
					// Called from both CreateFile or UpdateFile to handle both
 | 
				
			||||||
func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileOptions) (*api.FileResponse, error) {
 | 
					func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileOptions) (*api.FileResponse, error) {
 | 
				
			||||||
	if !canWriteFiles(ctx.Repo) {
 | 
						if !canWriteFiles(ctx.Repo) {
 | 
				
			||||||
 | 
				
			|||||||
@ -2793,6 +2793,15 @@
 | 
				
			|||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "$ref": "#/responses/FileResponse"
 | 
					            "$ref": "#/responses/FileResponse"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "403": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/error"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "404": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/notFound"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "422": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/error"
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@ -2842,6 +2851,15 @@
 | 
				
			|||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "201": {
 | 
					          "201": {
 | 
				
			||||||
            "$ref": "#/responses/FileResponse"
 | 
					            "$ref": "#/responses/FileResponse"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "403": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/error"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "404": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/notFound"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "422": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/error"
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user