github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/pkg/platform/api/buildplanner/response/commit.go (about) 1 package response 2 3 import ( 4 "encoding/json" 5 6 "github.com/ActiveState/cli/internal/errs" 7 "github.com/ActiveState/cli/internal/locale" 8 "github.com/ActiveState/cli/internal/logging" 9 "github.com/ActiveState/cli/pkg/platform/api/buildplanner/types" 10 "github.com/go-openapi/strfmt" 11 ) 12 13 type ProjectCommitResponse struct { 14 Project *ProjectResponse `json:"project"` 15 } 16 17 // PostProcess must satisfy gqlclient.PostProcessor interface 18 func (c *ProjectCommitResponse) PostProcess() error { 19 if c.Project == nil { 20 return errs.New("Project is nil") 21 } 22 23 if IsErrorResponse(c.Project.Type) { 24 return ProcessProjectError(c.Project, "Could not get build from project response") 25 } 26 27 if c.Project.Commit == nil { 28 return errs.New("Commit is nil") 29 } 30 31 if c.Project == nil { 32 return errs.New("Project is nil") 33 } 34 35 if IsErrorResponse(c.Project.Type) { 36 return ProcessProjectError(c.Project, "Could not get build from project response") 37 } 38 39 if c.Project.Commit == nil { 40 return errs.New("Commit is nil") 41 } 42 43 if IsErrorResponse(c.Project.Commit.Type) { 44 return ProcessCommitError(c.Project.Commit, "Could not get build from commit from project response") 45 } 46 47 if c.Project.Commit.Build == nil { 48 return errs.New("Commit does not contain build") 49 } 50 51 if IsErrorResponse(c.Project.Commit.Build.Type) { 52 return ProcessBuildError(c.Project.Commit.Build, "Could not get build from project commit response") 53 } 54 55 return nil 56 } 57 58 func ProcessBuildError(build *BuildResponse, fallbackMessage string) error { 59 logging.Debug("ProcessBuildError: build.Type=%s", build.Type) 60 if build.Type == types.PlanningErrorType { 61 return processPlanningError(build.Message, build.SubErrors) 62 } else if build.Error == nil { 63 return errs.New(fallbackMessage) 64 } 65 66 return locale.NewInputError("err_buildplanner_build", "Encountered error processing build response") 67 } 68 69 func processPlanningError(message string, subErrors []*BuildExprLocation) error { 70 var errs []string 71 var isTransient bool 72 73 if message != "" { 74 errs = append(errs, message) 75 } 76 77 for _, se := range subErrors { 78 if se.Type != types.RemediableSolveErrorType && se.Type != types.GenericSolveErrorType { 79 continue 80 } 81 82 if se.Message != "" { 83 errs = append(errs, se.Message) 84 isTransient = se.IsTransient 85 } 86 87 for _, ve := range se.ValidationErrors { 88 if ve.Error != "" { 89 errs = append(errs, ve.Error) 90 } 91 } 92 } 93 return &BuildPlannerError{ 94 ValidationErrors: errs, 95 IsTransient: isTransient, 96 } 97 } 98 99 func ProcessProjectError(project *ProjectResponse, fallbackMessage string) error { 100 if project.Type == types.NotFoundErrorType { 101 return errs.AddTips( 102 locale.NewInputError("err_buildplanner_project_not_found", "Unable to find project, received message: {{.V0}}", project.Message), 103 locale.T("tip_private_project_auth"), 104 ) 105 } 106 107 return errs.New(fallbackMessage) 108 } 109 110 // PlanningError represents an error that occurred during planning. 111 type PlanningError struct { 112 SubErrors []*BuildExprLocation `json:"subErrors"` 113 } 114 115 // BuildExprLocation represents a location in the build script where an error occurred. 116 type BuildExprLocation struct { 117 Type string `json:"__typename"` 118 Path string `json:"path"` 119 Message string `json:"message"` 120 IsTransient bool `json:"isTransient"` 121 ValidationErrors []*SolverErrorValidationError `json:"validationErrors"` 122 *RemediableSolveError 123 } 124 125 // Commit contains the build and any errors. 126 type Commit struct { 127 Type string `json:"__typename"` 128 AtTime strfmt.DateTime `json:"atTime"` 129 Expression json.RawMessage `json:"expr"` 130 CommitID strfmt.UUID `json:"commitId"` 131 Build *BuildResponse `json:"build"` 132 *Error 133 *ParseError 134 *ForbiddenError 135 *HeadOnBranchMovedError 136 *NoChangeSinceLastCommitError 137 }