Skip to content

Commit 3ef1501

Browse files
authored
Merge pull request ActiveState#3579 from ActiveState/mitchell/dx-2855
Implement user-facing errors for environment setup commands.
2 parents 4a9f51c + bdd8b3c commit 3ef1501

File tree

6 files changed

+73
-33
lines changed

6 files changed

+73
-33
lines changed

internal/locale/locales/en-us.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,6 @@ err_incompatible_move_file_dir:
646646
other: |
647647
Could not move [NOTICE]{{.V0}}[/RESET] to [NOTICE]{{.V1}}[/RESET]. One is a file, the other a directory.
648648
This indicates that the requested build may be corrupted.
649-
err_init_lang:
650-
other: "Invalid language: {{.V0}}@{{.V1}}"
651649
initializing_project:
652650
other: |
653651
Initializing Project
@@ -1217,8 +1215,6 @@ err_findproject_notfound:
12171215
other: "Could not load project [ACTIONABLE]{{.V0}}[/RESET] from path: [ACTIONABLE]{{.V1}}[/RESET]"
12181216
arg_state_shell_namespace_description:
12191217
other: The namespace of the project you wish to start a virtual environment shell/prompt for, or just the project name if previously used
1220-
err_language_by_commit:
1221-
other: Could not get language from commit ID {{.V0}}
12221218
err_parse_project:
12231219
other: Could not parse project file at {{.V0}}
12241220
err_uninstall_privilege_mismatch:

internal/runbits/checkout/checkout.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ package checkout
33
import (
44
"path/filepath"
55

6-
"github.com/ActiveState/cli/internal/locale"
7-
"github.com/ActiveState/cli/internal/primer"
8-
"github.com/ActiveState/cli/internal/runbits/buildscript"
96
"github.com/go-openapi/strfmt"
107

118
"github.com/ActiveState/cli/internal/constants"
129
"github.com/ActiveState/cli/internal/errs"
1310
"github.com/ActiveState/cli/internal/fileutils"
1411
"github.com/ActiveState/cli/internal/language"
1512
"github.com/ActiveState/cli/internal/osutils"
13+
"github.com/ActiveState/cli/internal/primer"
14+
"github.com/ActiveState/cli/internal/runbits/buildscript"
1615
"github.com/ActiveState/cli/internal/runbits/git"
1716
"github.com/ActiveState/cli/pkg/localcommit"
1817
"github.com/ActiveState/cli/pkg/platform/api/mono/mono_models"
@@ -47,6 +46,7 @@ func (e errCommitDoesNotBelong) Error() string {
4746
}
4847

4948
var errNoCommitID = errs.New("commitID is nil")
49+
var ErrNoOrg = errs.New("unable to get org name")
5050

5151
func New(repo git.Repository, prime primeable) *Checkout {
5252
return &Checkout{repo, prime}
@@ -87,7 +87,7 @@ func (r *Checkout) Run(ns *project.Namespaced, branchName, cachePath, targetPath
8787
if !noClone && repoURL != nil && *repoURL != "" {
8888
err := r.repo.CloneProject(ns.Owner, ns.Project, path, r.prime.Output(), r.prime.Analytics())
8989
if err != nil {
90-
return "", locale.WrapError(err, "err_clone_project", "Could not clone associated git repository")
90+
return "", errs.Wrap(err, "Could not clone associated git repository")
9191
}
9292
}
9393
} else if commitID == nil {
@@ -119,7 +119,7 @@ func (r *Checkout) fetchProject(
119119
// the project and create the project file
120120
pj, err := model.FetchProjectByName(ns.Owner, ns.Project, r.prime.Auth())
121121
if err != nil {
122-
return "", "", nil, "", "", nil, locale.WrapError(err, "err_fetch_project", "", ns.String())
122+
return "", "", nil, "", "", nil, errs.Wrap(err, "Unable to fetch project '%s'", ns.String())
123123
}
124124
proj := pj.Name
125125

@@ -144,7 +144,7 @@ func (r *Checkout) fetchProject(
144144
case branchName != "":
145145
branch, err = model.BranchForProjectByName(pj, branchName)
146146
if err != nil {
147-
return "", "", nil, "", "", nil, locale.WrapError(err, "err_fetch_branch", "", branchName)
147+
return "", "", nil, "", "", nil, errs.Wrap(err, "Could not get branch '%s'", branchName)
148148
}
149149
commitID = branch.CommitID
150150

@@ -175,7 +175,7 @@ func (r *Checkout) fetchProject(
175175
return "", "", nil, "", "", nil, errs.Wrap(err, "Unable to get the project's org")
176176
}
177177
if len(owners) == 0 {
178-
return "", "", nil, "", "", nil, locale.NewInputError("err_no_org_name", "Your project's organization name could not be found")
178+
return "", "", nil, "", "", nil, ErrNoOrg
179179
}
180180
owner := owners[0].URLName
181181

@@ -211,7 +211,7 @@ func CreateProjectFiles(checkoutPath, cachePath, owner, name, branch, commitID,
211211
func getLanguage(commitID strfmt.UUID, auth *authentication.Auth) (language.Language, error) {
212212
modelLanguage, err := model.LanguageByCommit(commitID, auth)
213213
if err != nil {
214-
return language.Unset, locale.WrapError(err, "err_language_by_commit", "", string(commitID))
214+
return language.Unset, errs.Wrap(err, "Could not get language from commit ID '%s'", string(commitID))
215215
}
216216

217217
return language.MakeByNameAndVersion(modelLanguage.Name, modelLanguage.Version), nil

internal/runners/checkout/checkout.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package checkout
22

33
import (
4+
"errors"
45
"os"
56
"path/filepath"
67
"strings"
@@ -77,6 +78,19 @@ func NewCheckout(prime primeable) *Checkout {
7778
}
7879
}
7980

81+
func rationalizeError(rerr *error) {
82+
if rerr == nil {
83+
return
84+
}
85+
86+
switch {
87+
case errors.Is(*rerr, checkout.ErrNoOrg):
88+
*rerr = errs.WrapUserFacing(*rerr,
89+
locale.Tl("err_no_org_name", "Your project's organization name could not be found"),
90+
errs.SetInput())
91+
}
92+
}
93+
8094
func (u *Checkout) Run(params *Params) (rerr error) {
8195
var err error
8296
var ns *project.Namespaced
@@ -101,6 +115,7 @@ func (u *Checkout) Run(params *Params) (rerr error) {
101115
}
102116

103117
defer func() { runtime_runbit.RationalizeSolveError(u.prime.Project(), u.auth, &rerr) }()
118+
defer rationalizeError(&rerr)
104119

105120
logging.Debug("Checking out %s to %s", ns.String(), params.PreferredPath)
106121

@@ -113,7 +128,7 @@ func (u *Checkout) Run(params *Params) (rerr error) {
113128

114129
proj, err := project.FromPath(projectDir)
115130
if err != nil {
116-
return locale.WrapError(err, "err_project_frompath")
131+
return errs.Wrap(err, "Could not read created project file")
117132
}
118133
u.prime.SetProject(proj)
119134

internal/runners/initialize/init.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"github.com/ActiveState/cli/internal/primer"
2121
"github.com/ActiveState/cli/internal/runbits/buildscript"
2222
"github.com/ActiveState/cli/internal/runbits/dependencies"
23-
"github.com/ActiveState/cli/internal/runbits/errors"
2423
"github.com/ActiveState/cli/internal/runbits/org"
2524
"github.com/ActiveState/cli/internal/runbits/rationalize"
2625
"github.com/ActiveState/cli/internal/runbits/runtime"
@@ -90,6 +89,8 @@ func (e errUnrecognizedLanguage) Error() string {
9089
return fmt.Sprintf("unrecognized language: %s", e.Name)
9190
}
9291

92+
var errDeleteProjectAfterError = errs.New("could not delete initialized project")
93+
9394
// New returns a prepared ptr to Initialize instance.
9495
func New(prime primeable) *Initialize {
9596
return &Initialize{prime, prime.Auth(), prime.Config(), prime.Output(), prime.Analytics(), prime.SvcModel()}
@@ -164,24 +165,23 @@ func (r *Initialize) Run(params *RunParams) (rerr error) {
164165

165166
err := fileutils.MkdirUnlessExists(path)
166167
if err != nil {
167-
return locale.WrapError(err, "err_init_preparedir", "Could not create directory at [NOTICE]{{.V0}}[/RESET]. Error: {{.V1}}", params.Path, err.Error())
168+
return errs.Wrap(err, "Could not create directory '%s'", params.Path)
168169
}
169170

170171
path, err = filepath.Abs(params.Path)
171172
if err != nil {
172-
return locale.WrapExternalError(err, "err_init_abs_path", "Could not determine absolute path to [NOTICE]{{.V0}}[/RESET]. Error: {{.V1}}", path, err.Error())
173+
return errs.Wrap(err, "Could not determine absolute path to '%s'", params.Path)
173174
}
174175

175176
var languageName, languageVersion string
176-
var inferred bool
177177
if params.Language != "" {
178178
langParts := strings.Split(params.Language, "@")
179179
languageName = langParts[0]
180180
if len(langParts) > 1 {
181181
languageVersion = langParts[1]
182182
}
183183
} else {
184-
languageName, languageVersion, inferred = inferLanguage(r.config, r.auth)
184+
languageName, languageVersion, _ = inferLanguage(r.config, r.auth)
185185
}
186186

187187
if languageName == "" {
@@ -200,11 +200,7 @@ func (r *Initialize) Run(params *RunParams) (rerr error) {
200200

201201
version, err := deriveVersion(lang, languageVersion, r.auth)
202202
if err != nil {
203-
if inferred || errors.IsReportableError(err) {
204-
return locale.WrapError(err, "err_init_lang", "", languageName, languageVersion)
205-
} else {
206-
return locale.WrapExternalError(err, "err_init_lang", "", languageName, languageVersion)
207-
}
203+
return errs.Wrap(err, "Unable to get language version")
208204
}
209205

210206
resolvedOwner, err = org.Get(paramOwner, r.auth, r.config)
@@ -226,7 +222,7 @@ func (r *Initialize) Run(params *RunParams) (rerr error) {
226222

227223
pjfile, err := projectfile.Create(createParams)
228224
if err != nil {
229-
return locale.WrapError(err, "err_init_pjfile", "Could not create project file")
225+
return errs.Wrap(err, "Could not create project file")
230226
}
231227

232228
// If an error occurs, remove the created activestate.yaml file so the user can try again.
@@ -296,7 +292,7 @@ func (r *Initialize) Run(params *RunParams) (rerr error) {
296292
err2 := model.DeleteProject(namespace.Owner, namespace.Project, r.auth)
297293
if err2 != nil {
298294
multilog.Error("Error deleting remotely created project after runtime setup error: %v", errs.JoinMessage(err2))
299-
return locale.WrapError(err, "err_init_refresh_delete_project", "Could not setup runtime after init, and could not delete newly created Platform project. Please delete it manually before trying again")
295+
return errDeleteProjectAfterError
300296
}
301297
return errs.Wrap(err, "Failed to fetch build result")
302298
}

internal/runners/initialize/rationalize.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,10 @@ func rationalizeError(owner, project string, rerr *error) {
8383
errs.SetTips(locale.T("err_init_authenticated")))
8484
}
8585

86+
case errors.Is(*rerr, errDeleteProjectAfterError):
87+
*rerr = errs.WrapUserFacing(*rerr,
88+
locale.Tl("err_init_refresh_delete_project", "Could not setup runtime after init, and could not delete newly created Platform project. Please delete it manually before trying again"),
89+
)
90+
8691
}
8792
}

internal/runners/swtch/switch.go

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package swtch
22

33
import (
4+
"errors"
5+
46
"github.com/ActiveState/cli/internal/analytics"
57
"github.com/ActiveState/cli/internal/config"
68
"github.com/ActiveState/cli/internal/errs"
@@ -74,6 +76,15 @@ func (b branchIdentifier) Locale() string {
7476
return locale.Tl("branch_identifier_type", "branch")
7577
}
7678

79+
type errCommitNotOnBranch struct {
80+
commitID string
81+
branch string
82+
}
83+
84+
func (e errCommitNotOnBranch) Error() string {
85+
return "commit is not on branch"
86+
}
87+
7788
func New(prime primeable) *Switch {
7889
return &Switch{
7990
prime: prime,
@@ -86,7 +97,24 @@ func New(prime primeable) *Switch {
8697
}
8798
}
8899

89-
func (s *Switch) Run(params SwitchParams) error {
100+
func rationalizeError(rerr *error) {
101+
if rerr == nil {
102+
return
103+
}
104+
105+
var commitNotOnBranchErr *errCommitNotOnBranch
106+
107+
switch {
108+
case errors.As(*rerr, &commitNotOnBranchErr):
109+
*rerr = errs.WrapUserFacing(*rerr,
110+
locale.Tl("err_identifier_branch_not_on_branch", "Commit does not belong to history for branch [ACTIONABLE]{{.V0}}[/RESET]", commitNotOnBranchErr.branch),
111+
errs.SetInput(),
112+
)
113+
}
114+
}
115+
116+
func (s *Switch) Run(params SwitchParams) (rerr error) {
117+
defer rationalizeError(&rerr)
90118
logging.Debug("ExecuteSwitch")
91119

92120
if s.project == nil {
@@ -96,27 +124,27 @@ func (s *Switch) Run(params SwitchParams) error {
96124

97125
project, err := model.LegacyFetchProjectByName(s.project.Owner(), s.project.Name())
98126
if err != nil {
99-
return locale.WrapError(err, "err_fetch_project", "", s.project.Namespace().String())
127+
return errs.Wrap(err, "Could not fetch project '%s'", s.project.Namespace().String())
100128
}
101129

102130
identifier, err := resolveIdentifier(project, params.Identifier)
103131
if err != nil {
104-
return locale.WrapError(err, "err_resolve_identifier", "Could not resolve identifier '{{.V0}}'", params.Identifier)
132+
return errs.Wrap(err, "Could not resolve identifier '%s'", params.Identifier)
105133
}
106134

107135
if id, ok := identifier.(branchIdentifier); ok {
108136
err = s.project.Source().SetBranch(id.branch.Label)
109137
if err != nil {
110-
return locale.WrapError(err, "err_switch_set_branch", "Could not update branch")
138+
return errs.Wrap(err, "Could not update branch")
111139
}
112140
}
113141

114142
belongs, err := model.CommitBelongsToBranch(s.project.Owner(), s.project.Name(), s.project.BranchName(), identifier.CommitID(), s.auth)
115143
if err != nil {
116-
return locale.WrapError(err, "err_identifier_branch", "Could not determine if commit belongs to branch")
144+
return errs.Wrap(err, "Could not determine if commit belongs to branch")
117145
}
118146
if !belongs {
119-
return locale.NewInputError("err_identifier_branch_not_on_branch", "Commit does not belong to history for branch [ACTIONABLE]{{.V0}}[/RESET]", s.project.BranchName())
147+
return &errCommitNotOnBranch{identifier.CommitID().String(), s.project.BranchName()}
120148
}
121149

122150
err = localcommit.Set(s.project.Dir(), identifier.CommitID().String())
@@ -126,7 +154,7 @@ func (s *Switch) Run(params SwitchParams) error {
126154

127155
_, err = runtime_runbit.Update(s.prime, trigger.TriggerSwitch)
128156
if err != nil {
129-
return locale.WrapError(err, "err_refresh_runtime")
157+
return errs.Wrap(err, "Could not setup runtime")
130158
}
131159

132160
s.out.Print(output.Prepare(
@@ -148,7 +176,7 @@ func resolveIdentifier(project *mono_models.Project, idParam string) (identifier
148176

149177
branch, err := model.BranchForProjectByName(project, idParam)
150178
if err != nil {
151-
return nil, locale.WrapError(err, "err_identifier_branch", "Could not get branch '{{.V0}}' for current project", idParam)
179+
return nil, errs.Wrap(err, "Could not get branch '%s'", idParam)
152180

153181
}
154182

0 commit comments

Comments
 (0)