github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/runbits/runtime/rationalize.go (about) 1 package runtime 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 8 "github.com/ActiveState/cli/internal/constants" 9 "github.com/ActiveState/cli/internal/errs" 10 "github.com/ActiveState/cli/internal/locale" 11 "github.com/ActiveState/cli/internal/runbits/rationalize" 12 "github.com/ActiveState/cli/pkg/platform/api" 13 bpResp "github.com/ActiveState/cli/pkg/platform/api/buildplanner/response" 14 "github.com/ActiveState/cli/pkg/platform/authentication" 15 "github.com/ActiveState/cli/pkg/platform/model" 16 "github.com/ActiveState/cli/pkg/platform/runtime" 17 "github.com/ActiveState/cli/pkg/platform/runtime/setup" 18 "github.com/ActiveState/cli/pkg/platform/runtime/setup/buildlog" 19 "github.com/ActiveState/cli/pkg/project" 20 ) 21 22 func rationalizeError(auth *authentication.Auth, proj *project.Project, rerr *error) { 23 if *rerr == nil { 24 return 25 } 26 var noMatchingPlatformErr *model.ErrNoMatchingPlatform 27 var artifactDownloadErr *setup.ArtifactDownloadError 28 var buildPlannerErr *bpResp.BuildPlannerError 29 var artifactCachedBuildErr *setup.ArtifactCachedBuildFailed 30 var artifactBuildErr *buildlog.ArtifactBuildError 31 32 switch { 33 case errors.Is(*rerr, rationalize.ErrHeadless): 34 *rerr = errs.WrapUserFacing(*rerr, 35 locale.Tr("err_headless", proj.URL()), 36 errs.SetInput()) 37 38 // Could not find a platform that matches on the given branch, so suggest alternate branches if ones exist 39 case errors.As(*rerr, &noMatchingPlatformErr): 40 branches, err := model.BranchNamesForProjectFiltered(proj.Owner(), proj.Name(), proj.BranchName()) 41 if err == nil && len(branches) > 0 { 42 // Suggest alternate branches 43 *rerr = errs.NewUserFacing(locale.Tr( 44 "err_alternate_branches", 45 noMatchingPlatformErr.HostPlatform, noMatchingPlatformErr.HostArch, 46 proj.BranchName(), strings.Join(branches, "\n - "))) 47 } else { 48 libcErr := noMatchingPlatformErr.LibcVersion != "" 49 *rerr = errs.NewUserFacing( 50 locale.Tr("err_no_platform_data_remains", noMatchingPlatformErr.HostPlatform, noMatchingPlatformErr.HostArch), 51 errs.SetIf(libcErr, errs.SetInput()), 52 errs.SetIf(libcErr, errs.SetTips(locale.Tr("err_user_libc_solution", api.GetPlatformURL(fmt.Sprintf("%s/%s", proj.NamespaceString(), "customize")).String()))), 53 ) 54 } 55 56 // If there was an artifact download error, say so, rather than reporting a generic "could not 57 // update runtime" error. 58 case errors.As(*rerr, &artifactDownloadErr): 59 *rerr = errs.WrapUserFacing(*rerr, 60 locale.Tl("err_runtime_setup_download", "Your runtime could not be installed or updated because one or more artifacts failed to download."), 61 errs.SetInput(), 62 errs.SetTips(locale.Tr("err_user_network_solution", constants.ForumsURL)), 63 ) 64 65 // We communicate buildplanner errors verbatim as the intend is that these are curated by the buildplanner 66 case errors.As(*rerr, &buildPlannerErr): 67 *rerr = errs.WrapUserFacing(*rerr, 68 buildPlannerErr.LocalizedError(), 69 errs.SetIf(buildPlannerErr.InputError(), errs.SetInput())) 70 71 // User has modified the buildscript and needs to run `state commit` 72 case errors.Is(*rerr, runtime.NeedsCommitError): 73 *rerr = errs.WrapUserFacing(*rerr, locale.T("notice_commit_build_script"), errs.SetInput()) 74 75 // Buildscript is missing and needs to be recreated 76 case errors.Is(*rerr, runtime.NeedsBuildscriptResetError): 77 *rerr = errs.WrapUserFacing(*rerr, locale.T("notice_needs_buildscript_reset"), errs.SetInput()) 78 79 // Artifact cached build errors 80 case errors.As(*rerr, &artifactCachedBuildErr): 81 errMsg := locale.Tr("err_build_artifact_failed_msg", artifactCachedBuildErr.Artifact.Name()) 82 *rerr = errs.WrapUserFacing(*rerr, 83 locale.Tr("err_build_artifact_failed", 84 errMsg, strings.Join(artifactCachedBuildErr.Artifact.Errors, "\n"), artifactCachedBuildErr.Artifact.LogURL, 85 ), 86 errs.SetInput(), 87 ) 88 89 // Artifact build errors 90 case errors.As(*rerr, &artifactBuildErr): 91 errMsg := locale.Tr("err_build_artifact_failed_msg", artifactBuildErr.Artifact.Name()) 92 *rerr = errs.WrapUserFacing(*rerr, 93 locale.Tr("err_build_artifact_failed", 94 errMsg, artifactBuildErr.Message.ErrorMessage, artifactBuildErr.Message.LogURI, 95 ), 96 errs.SetInput(), 97 ) 98 99 // If updating failed due to unidentified errors, and the user is not authenticated, add a tip suggesting that they authenticate as 100 // this may be a private project. 101 // Note since we cannot assert the actual error type we do not wrap this as user-facing, as we do not know what we're 102 // dealing with so the localized underlying errors are more appropriate. 103 default: 104 // Add authentication tip if we could not assert the error type 105 // This must only happen after all error assertions have failed, because if we can assert the error we can give 106 // an appropriate message, rather than a vague tip that suggests MAYBE this is a private project. 107 if !auth.Authenticated() { 108 *rerr = errs.AddTips(*rerr, 109 locale.T("tip_private_project_auth"), 110 ) 111 } 112 113 } 114 }