Skip to content

Commit 0a47604

Browse files
committed
Use errors.AsType for error unwrapping
1 parent 4d6e9eb commit 0a47604

5 files changed

Lines changed: 40 additions & 33 deletions

File tree

docs/docs/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ id: changelog
33
title: Changelog
44
---
55

6+
## [Unreleased](https://github.com/lets-cli/lets/releases/tag/v0.0.X)
7+
8+
* `[Refactoring]` Use Go 1.26 `errors.AsType` for type-safe error unwrapping.
9+
610
## [0.0.61](https://github.com/lets-cli/lets/releases/tag/v0.0.61)
711

812
* `[Changed]` Install script now installs to `$HOME/.lets/bin`, exposes `lets` through a user PATH symlink, and stops on old non-Homebrew `/usr/local/bin/lets` installs. Issue [#121](https://github.com/lets-cli/lets/issues/121)

internal/cli/cli.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,7 @@ func Main(version string, buildDate string) int {
127127
defer cancelUpdateCheck()
128128

129129
if err := rootCmd.ExecuteContext(ctx); err != nil {
130-
var depErr *executor.DependencyError
131-
if errors.As(err, &depErr) {
130+
if depErr, ok := errors.AsType[*executor.DependencyError](err); ok {
132131
log.Errorf("%s", depErr.TreeMessage())
133132
log.Errorf("%s", depErr.FailureMessage())
134133

@@ -167,9 +166,13 @@ func getContext() context.Context {
167166
}
168167

169168
func getExitCode(err error, defaultCode int) int {
170-
var exitCoder interface{ ExitCode() int }
171-
if errors.As(err, &exitCoder) {
172-
return exitCoder.ExitCode()
169+
type errorWithExitCode interface {
170+
error
171+
ExitCode() int
172+
}
173+
174+
if errWithExitCode, ok := errors.AsType[errorWithExitCode](err); ok {
175+
return errWithExitCode.ExitCode()
173176
}
174177

175178
return defaultCode

internal/cmd/root_test.go

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ import (
1212
"github.com/spf13/cobra"
1313
)
1414

15+
type testErrorWithExitCode interface {
16+
error
17+
ExitCode() int
18+
}
19+
20+
func requireErrorWithExitCode(t *testing.T, err error) testErrorWithExitCode {
21+
t.Helper()
22+
23+
errWithExitCode, ok := errors.AsType[testErrorWithExitCode](err)
24+
if !ok {
25+
t.Fatal("expected error with exit code")
26+
}
27+
28+
return errWithExitCode
29+
}
30+
1531
func newTestRootCmd(args []string) (rootCmd *cobra.Command) {
1632
root := CreateRootCommand("v0.0.0-test", "")
1733
root.SetArgs(args)
@@ -91,12 +107,9 @@ func TestRootCmdWithConfig(t *testing.T) {
91107
t.Fatal("expected unknown command error")
92108
}
93109

94-
var exitCoder interface{ ExitCode() int }
95-
if !errors.As(err, &exitCoder) {
96-
t.Fatal("expected error with exit code")
97-
}
110+
errWithExitCode := requireErrorWithExitCode(t, err)
98111

99-
if exitCode := exitCoder.ExitCode(); exitCode != 2 {
112+
if exitCode := errWithExitCode.ExitCode(); exitCode != 2 {
100113
t.Fatalf("expected exit code 2, got %d", exitCode)
101114
}
102115

@@ -121,12 +134,9 @@ func TestRootCmdWithConfig(t *testing.T) {
121134
t.Fatal("expected unknown command error")
122135
}
123136

124-
var exitCoder interface{ ExitCode() int }
125-
if !errors.As(err, &exitCoder) {
126-
t.Fatal("expected error with exit code")
127-
}
137+
errWithExitCode := requireErrorWithExitCode(t, err)
128138

129-
if exitCode := exitCoder.ExitCode(); exitCode != 2 {
139+
if exitCode := errWithExitCode.ExitCode(); exitCode != 2 {
130140
t.Fatalf("expected exit code 2, got %d", exitCode)
131141
}
132142

@@ -247,12 +257,9 @@ func TestSelfCmd(t *testing.T) {
247257
t.Fatal("expected unknown command error")
248258
}
249259

250-
var exitCoder interface{ ExitCode() int }
251-
if !errors.As(err, &exitCoder) {
252-
t.Fatal("expected error with exit code")
253-
}
260+
errWithExitCode := requireErrorWithExitCode(t, err)
254261

255-
if exitCode := exitCoder.ExitCode(); exitCode != 2 {
262+
if exitCode := errWithExitCode.ExitCode(); exitCode != 2 {
256263
t.Fatalf("expected exit code 2, got %d", exitCode)
257264
}
258265

@@ -283,12 +290,9 @@ func TestSelfCmd(t *testing.T) {
283290
t.Fatal("expected unknown command error")
284291
}
285292

286-
var exitCoder interface{ ExitCode() int }
287-
if !errors.As(err, &exitCoder) {
288-
t.Fatal("expected error with exit code")
289-
}
293+
errWithExitCode := requireErrorWithExitCode(t, err)
290294

291-
if exitCode := exitCoder.ExitCode(); exitCode != 2 {
295+
if exitCode := errWithExitCode.ExitCode(); exitCode != 2 {
292296
t.Fatalf("expected exit code 2, got %d", exitCode)
293297
}
294298

internal/executor/dependency_error.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,15 @@ func (e *DependencyError) Unwrap() error { return e.Err }
2525

2626
// ExitCode propagates the exit code from the innermost ExecuteError, or returns 1.
2727
func (e *DependencyError) ExitCode() int {
28-
var exitErr *ExecuteError
29-
if errors.As(e.Err, &exitErr) {
28+
if exitErr, ok := errors.AsType[*ExecuteError](e.Err); ok {
3029
return exitErr.ExitCode()
3130
}
3231

3332
return 1
3433
}
3534

3635
func (e *DependencyError) FailureMessage() string {
37-
var executeErr *ExecuteError
38-
if errors.As(e.Err, &executeErr) {
36+
if executeErr, ok := errors.AsType[*ExecuteError](e.Err); ok {
3937
return executeErr.Cause().Error()
4038
}
4139

@@ -67,8 +65,7 @@ func (e *DependencyError) TreeMessage() string {
6765
// prependToChain prepends name to the chain in err if err is already a *DependencyError,
6866
// otherwise wraps err in a new single-element DependencyError.
6967
func prependToChain(name string, err error) error {
70-
var depErr *DependencyError
71-
if errors.As(err, &depErr) {
68+
if depErr, ok := errors.AsType[*DependencyError](err); ok {
7269
return &DependencyError{Chain: append([]string{name}, depErr.Chain...), Err: depErr.Err}
7370
}
7471

internal/executor/executor.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ func (e *ExecuteError) Cause() error {
3939

4040
// ExitCode will return exit code from underlying ExitError or returns default error code.
4141
func (e *ExecuteError) ExitCode() int {
42-
var exitErr *exec.ExitError
43-
if ok := errors.As(e.err, &exitErr); ok {
42+
if exitErr, ok := errors.AsType[*exec.ExitError](e.err); ok {
4443
return exitErr.ExitCode()
4544
}
4645

0 commit comments

Comments
 (0)