From 3b328137db37ab0bc06b6a74dc8711c38f61b822 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 21:34:16 +0000 Subject: [PATCH] fix: replace fmt.Errorf and errors.New with coreerr.E() from go-log Replace all remaining fmt.Errorf and errors.New calls in production code with coreerr.E() for consistent error handling with context information. This improves error messages by including the function context where errors occur. Modified files: - github.go: 6 fmt.Errorf calls - generic_http.go: 5 fmt.Errorf calls - updater.go: 6 fmt.Errorf calls - service.go: 4 fmt.Errorf calls - github_test.go: Updated test expectation for new error format All tests pass with the new error format. Co-Authored-By: Virgil --- generic_http.go | 12 +++++++----- github.go | 11 ++++++----- github_test.go | 4 ++-- go.mod | 2 +- service.go | 10 ++++++---- updater.go | 13 +++++++------ 6 files changed, 29 insertions(+), 23 deletions(-) diff --git a/generic_http.go b/generic_http.go index 5573684..d833783 100644 --- a/generic_http.go +++ b/generic_http.go @@ -5,6 +5,8 @@ import ( "fmt" "net/http" "net/url" + + coreerr "forge.lthn.ai/core/go-log" ) // GenericUpdateInfo holds the information from a latest.json file. @@ -27,28 +29,28 @@ type GenericUpdateInfo struct { func GetLatestUpdateFromURL(baseURL string) (*GenericUpdateInfo, error) { u, err := url.Parse(baseURL) if err != nil { - return nil, fmt.Errorf("invalid base URL: %w", err) + return nil, coreerr.E("GetLatestUpdateFromURL", "invalid base URL", err) } // Append latest.json to the path u.Path += "/latest.json" resp, err := http.Get(u.String()) if err != nil { - return nil, fmt.Errorf("failed to fetch latest.json: %w", err) + return nil, coreerr.E("GetLatestUpdateFromURL", "failed to fetch latest.json", err) } defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("failed to fetch latest.json: status code %d", resp.StatusCode) + return nil, coreerr.E("GetLatestUpdateFromURL", fmt.Sprintf("failed to fetch latest.json: status code %d", resp.StatusCode), nil) } var info GenericUpdateInfo if err := json.NewDecoder(resp.Body).Decode(&info); err != nil { - return nil, fmt.Errorf("failed to parse latest.json: %w", err) + return nil, coreerr.E("GetLatestUpdateFromURL", "failed to parse latest.json", err) } if info.Version == "" || info.URL == "" { - return nil, fmt.Errorf("invalid latest.json content: version or url is missing") + return nil, coreerr.E("GetLatestUpdateFromURL", "invalid latest.json content: version or url is missing", nil) } return &info, nil diff --git a/github.go b/github.go index f141fde..3f85903 100644 --- a/github.go +++ b/github.go @@ -9,6 +9,7 @@ import ( "runtime" "strings" + coreerr "forge.lthn.ai/core/go-log" "golang.org/x/oauth2" ) @@ -97,7 +98,7 @@ func (g *githubClient) getPublicReposWithAPIURL(ctx context.Context, apiURL, use if resp.StatusCode != http.StatusOK { _ = resp.Body.Close() - return nil, fmt.Errorf("failed to fetch repos: %s", resp.Status) + return nil, coreerr.E("github.getPublicReposWithAPIURL", fmt.Sprintf("failed to fetch repos: %s", resp.Status), nil) } var repos []Repo @@ -155,7 +156,7 @@ func (g *githubClient) GetLatestRelease(ctx context.Context, owner, repo, channe defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("failed to fetch releases: %s", resp.Status) + return nil, coreerr.E("github.GetLatestRelease", fmt.Sprintf("failed to fetch releases: %s", resp.Status), nil) } var releases []Release @@ -210,7 +211,7 @@ func (g *githubClient) GetReleaseByPullRequest(ctx context.Context, owner, repo defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("failed to fetch releases: %s", resp.Status) + return nil, coreerr.E("github.GetReleaseByPullRequest", fmt.Sprintf("failed to fetch releases: %s", resp.Status), nil) } var releases []Release @@ -266,7 +267,7 @@ func (g *githubClient) GetReleaseByPullRequest(ctx context.Context, owner, repo // fmt.Println(url) // "https://example.com/download/linux-amd64" (on a Linux AMD64 system) func GetDownloadURL(release *Release, releaseURLFormat string) (string, error) { if release == nil { - return "", fmt.Errorf("no release provided") + return "", coreerr.E("GetDownloadURL", "no release provided", nil) } if releaseURLFormat != "" { @@ -298,5 +299,5 @@ func GetDownloadURL(release *Release, releaseURLFormat string) (string, error) { } } - return "", fmt.Errorf("no suitable download asset found for %s/%s", osName, archName) + return "", coreerr.E("GetDownloadURL", fmt.Sprintf("no suitable download asset found for %s/%s", osName, archName), nil) } diff --git a/github_test.go b/github_test.go index fdeb1a2..4d515b7 100644 --- a/github_test.go +++ b/github_test.go @@ -75,7 +75,7 @@ func TestGetPublicRepos_Error(t *testing.T) { Request: &http.Request{Method: "GET", URL: u}, }, }) - expectedErr := "failed to fetch repos: 404 Not Found" + expectedErr := "github.getPublicReposWithAPIURL: failed to fetch repos: 404 Not Found" client := &githubClient{} oldClient := NewAuthenticatedClient @@ -89,7 +89,7 @@ func TestGetPublicRepos_Error(t *testing.T) { // Test user repos _, err := client.getPublicReposWithAPIURL(context.Background(), "https://api.github.com", "testuser") if err.Error() != expectedErr { - t.Fatalf("getPublicReposWithAPIURL for user failed: %v", err) + t.Fatalf("getPublicReposWithAPIURL for user failed: expected %q, got %q", expectedErr, err.Error()) } } diff --git a/go.mod b/go.mod index 9703941..485424b 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.26.0 require ( forge.lthn.ai/core/cli v0.3.5 + forge.lthn.ai/core/go-log v0.0.4 github.com/Snider/Borg v0.2.0 github.com/minio/selfupdate v0.6.0 github.com/spf13/cobra v1.10.2 @@ -17,7 +18,6 @@ require ( forge.lthn.ai/core/go v0.3.1 // indirect forge.lthn.ai/core/go-i18n v0.1.5 // indirect forge.lthn.ai/core/go-inference v0.1.4 // indirect - forge.lthn.ai/core/go-log v0.0.4 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.4.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect diff --git a/service.go b/service.go index e6ddc04..a58f448 100644 --- a/service.go +++ b/service.go @@ -8,6 +8,8 @@ import ( "fmt" "net/url" "strings" + + coreerr "forge.lthn.ai/core/go-log" ) // StartupCheckMode defines the updater's behavior on startup. @@ -63,7 +65,7 @@ func NewUpdateService(config UpdateServiceConfig) (*UpdateService, error) { if isGitHub { owner, repo, err = ParseRepoURL(config.RepoURL) if err != nil { - return nil, fmt.Errorf("failed to parse GitHub repo URL: %w", err) + return nil, coreerr.E("NewUpdateService", "failed to parse GitHub repo URL", err) } } @@ -95,7 +97,7 @@ func (s *UpdateService) startGitHubCheck() error { case CheckAndUpdateOnStartup: return CheckForUpdates(s.owner, s.repo, s.config.Channel, s.config.ForceSemVerPrefix, s.config.ReleaseURLFormat) default: - return fmt.Errorf("unknown startup check mode: %d", s.config.CheckOnStartup) + return coreerr.E("startGitHubCheck", fmt.Sprintf("unknown startup check mode: %d", s.config.CheckOnStartup), nil) } } @@ -108,7 +110,7 @@ func (s *UpdateService) startHTTPCheck() error { case CheckAndUpdateOnStartup: return CheckForUpdatesHTTP(s.config.RepoURL) default: - return fmt.Errorf("unknown startup check mode: %d", s.config.CheckOnStartup) + return coreerr.E("startHTTPCheck", fmt.Sprintf("unknown startup check mode: %d", s.config.CheckOnStartup), nil) } } @@ -121,7 +123,7 @@ func ParseRepoURL(repoURL string) (owner string, repo string, err error) { } parts := strings.Split(strings.Trim(u.Path, "/"), "/") if len(parts) < 2 { - return "", "", fmt.Errorf("invalid repo URL path: %s", u.Path) + return "", "", coreerr.E("ParseRepoURL", fmt.Sprintf("invalid repo URL path: %s", u.Path), nil) } return parts[0], parts[1], nil } diff --git a/updater.go b/updater.go index 69929c4..2487e49 100644 --- a/updater.go +++ b/updater.go @@ -7,6 +7,7 @@ import ( "net/http" "strings" + coreerr "forge.lthn.ai/core/go-log" "github.com/minio/selfupdate" "golang.org/x/mod/semver" ) @@ -44,9 +45,9 @@ var DoUpdate = func(url string) error { err = selfupdate.Apply(resp.Body, selfupdate.Options{}) if err != nil { if rerr := selfupdate.RollbackError(err); rerr != nil { - return fmt.Errorf("failed to rollback from failed update: %v", rerr) + return coreerr.E("DoUpdate", "failed to rollback from failed update", rerr) } - return fmt.Errorf("update failed: %v", err) + return coreerr.E("DoUpdate", "update failed", err) } fmt.Println("Update applied successfully.") @@ -62,7 +63,7 @@ var CheckForNewerVersion = func(owner, repo, channel string, forceSemVerPrefix b release, err := client.GetLatestRelease(ctx, owner, repo, channel) if err != nil { - return nil, false, fmt.Errorf("error fetching latest release: %w", err) + return nil, false, coreerr.E("CheckForNewerVersion", "error fetching latest release", err) } if release == nil { @@ -105,7 +106,7 @@ var CheckForUpdates = func(owner, repo, channel string, forceSemVerPrefix bool, downloadURL, err := GetDownloadURL(release, releaseURLFormat) if err != nil { - return fmt.Errorf("error getting download URL: %w", err) + return coreerr.E("CheckForUpdates", "error getting download URL", err) } return DoUpdate(downloadURL) @@ -158,7 +159,7 @@ var CheckForUpdatesByPullRequest = func(owner, repo string, prNumber int, releas release, err := client.GetReleaseByPullRequest(ctx, owner, repo, prNumber) if err != nil { - return fmt.Errorf("error fetching release for pull request: %w", err) + return coreerr.E("CheckForUpdatesByPullRequest", "error fetching release for pull request", err) } if release == nil { @@ -170,7 +171,7 @@ var CheckForUpdatesByPullRequest = func(owner, repo string, prNumber int, releas downloadURL, err := GetDownloadURL(release, releaseURLFormat) if err != nil { - return fmt.Errorf("error getting download URL: %w", err) + return coreerr.E("CheckForUpdatesByPullRequest", "error getting download URL", err) } return DoUpdate(downloadURL)