about summary refs log tree commit diff stats
path: root/internal/fetcher
diff options
context:
space:
mode:
authorAlan Pearce2025-03-12 22:39:51 +0100
committerAlan Pearce2025-03-12 22:39:51 +0100
commit9015baf955c94a806c01b3dcd5648c8e68ad2685 (patch)
tree5f59386c2ab31b6e45b85576e45a1fc8ae448ae0 /internal/fetcher
parent7bb77ff5729cc9434afee895a470fd3b4c12e6d1 (diff)
downloadsearchix-9015baf955c94a806c01b3dcd5648c8e68ad2685.tar.lz
searchix-9015baf955c94a806c01b3dcd5648c8e68ad2685.tar.zst
searchix-9015baf955c94a806c01b3dcd5648c8e68ad2685.zip
refactor: ensure errors have stack traces HEAD main
Diffstat (limited to 'internal/fetcher')
-rw-r--r--internal/fetcher/channel.go25
-rw-r--r--internal/fetcher/download.go25
-rw-r--r--internal/fetcher/http.go40
-rw-r--r--internal/fetcher/main.go6
-rw-r--r--internal/fetcher/nixpkgs-channel.go11
5 files changed, 50 insertions, 57 deletions
diff --git a/internal/fetcher/channel.go b/internal/fetcher/channel.go
index 8f0aa03..86e2c60 100644
--- a/internal/fetcher/channel.go
+++ b/internal/fetcher/channel.go
@@ -14,7 +14,7 @@ import (
 	"go.alanpearce.eu/searchix/internal/index"
 	"go.alanpearce.eu/x/log"
 
-	"github.com/pkg/errors"
+	"gitlab.com/tozd/go/errors"
 )
 
 type ChannelFetcher struct {
@@ -26,7 +26,7 @@ type ChannelFetcher struct {
 func NewChannelFetcher(
 	source *config.Source,
 	logger *log.Logger,
-) (*ChannelFetcher, error) {
+) (*ChannelFetcher, errors.E) {
 	switch source.Importer {
 	case config.Options:
 		return &ChannelFetcher{
@@ -34,14 +34,14 @@ func NewChannelFetcher(
 			Logger: logger,
 		}, nil
 	default:
-		return nil, fmt.Errorf("unsupported importer type %s", source.Importer)
+		return nil, errors.Errorf("unsupported importer type %s", source.Importer)
 	}
 }
 
 func (i *ChannelFetcher) FetchIfNeeded(
 	ctx context.Context,
 	sourceMeta *index.SourceMeta,
-) (f FetchedFiles, err error) {
+) (*FetchedFiles, errors.E) {
 	args := []string{
 		"--no-build-output",
 		"--timeout",
@@ -58,12 +58,9 @@ func (i *ChannelFetcher) FetchIfNeeded(
 
 	i.Logger.Debug("nix-build command", "args", args)
 	cmd := exec.CommandContext(ctx, "nix-build", args...)
-	var out []byte
-	out, err = cmd.Output()
+	out, err := cmd.Output()
 	if err != nil {
-		err = errors.WithMessage(err, "failed to run nix-build (--dry-run)")
-
-		return
+		return nil, errors.WithMessage(err, "failed to run nix-build (--dry-run)")
 	}
 
 	outPath := path.Join(strings.TrimSpace(string(out)), i.Source.OutputPath, "options.json")
@@ -80,14 +77,10 @@ func (i *ChannelFetcher) FetchIfNeeded(
 
 	file, err := os.Open(outPath)
 	if err != nil {
-		err = errors.WithMessage(err, "failed to open options.json")
-
-		return
+		return nil, errors.WithMessage(err, "failed to open options.json")
 	}
 
-	f = FetchedFiles{
+	return &FetchedFiles{
 		Options: file,
-	}
-
-	return
+	}, nil
 }
diff --git a/internal/fetcher/download.go b/internal/fetcher/download.go
index a34c838..6c5bae8 100644
--- a/internal/fetcher/download.go
+++ b/internal/fetcher/download.go
@@ -2,13 +2,12 @@ package fetcher
 
 import (
 	"context"
-	"fmt"
 	"net/url"
 
 	"go.alanpearce.eu/searchix/internal/config"
 	"go.alanpearce.eu/searchix/internal/index"
 
-	"github.com/pkg/errors"
+	"gitlab.com/tozd/go/errors"
 	"go.alanpearce.eu/x/log"
 )
 
@@ -21,7 +20,7 @@ type DownloadFetcher struct {
 func NewDownloadFetcher(
 	source *config.Source,
 	logger *log.Logger,
-) (*DownloadFetcher, error) {
+) (*DownloadFetcher, errors.E) {
 	switch source.Importer {
 	case config.Options:
 		return &DownloadFetcher{
@@ -29,7 +28,7 @@ func NewDownloadFetcher(
 			Logger: logger,
 		}, nil
 	default:
-		return nil, fmt.Errorf("unsupported importer type %s", source.Importer)
+		return nil, errors.Errorf("unsupported importer type %s", source.Importer)
 	}
 }
 
@@ -41,20 +40,18 @@ var files = map[string]string{
 func (i *DownloadFetcher) FetchIfNeeded(
 	ctx context.Context,
 	sourceMeta *index.SourceMeta,
-) (f FetchedFiles, err error) {
-	var fetchURL string
+) (*FetchedFiles, errors.E) {
+	f := &FetchedFiles{}
 	sourceUpdated := sourceMeta.Updated
 	for key, filename := range files {
-		fetchURL, err = url.JoinPath(i.Source.URL, filename)
-		if err != nil {
-			err = errors.WithMessagef(
-				err,
+		fetchURL, baseErr := url.JoinPath(i.Source.URL, filename)
+		if baseErr != nil {
+			return nil, errors.WithMessagef(
+				baseErr,
 				"could not build URL with elements %s and %s",
 				i.Source.URL,
 				filename,
 			)
-
-			return
 		}
 
 		i.Logger.Debug("preparing to fetch URL", "url", fetchURL)
@@ -63,7 +60,7 @@ func (i *DownloadFetcher) FetchIfNeeded(
 		if err != nil {
 			i.Logger.Warn("failed to fetch file", "url", fetchURL, "error", err)
 
-			return f, err
+			return nil, err
 		}
 		// don't bother to issue requests for the later files
 		if mtime.Before(sourceUpdated) {
@@ -81,5 +78,5 @@ func (i *DownloadFetcher) FetchIfNeeded(
 		}
 	}
 
-	return
+	return f, nil
 }
diff --git a/internal/fetcher/http.go b/internal/fetcher/http.go
index c5ec8fc..ba99c3a 100644
--- a/internal/fetcher/http.go
+++ b/internal/fetcher/http.go
@@ -11,7 +11,7 @@ import (
 	"go.alanpearce.eu/searchix/internal/config"
 
 	"github.com/andybalholm/brotli"
-	"github.com/pkg/errors"
+	"gitlab.com/tozd/go/errors"
 	"go.alanpearce.eu/x/log"
 )
 
@@ -36,17 +36,20 @@ func fetchFileIfNeeded(
 	log *log.Logger,
 	mtime time.Time,
 	url string,
-) (body io.ReadCloser, newMtime time.Time, err error) {
+) (io.ReadCloser, time.Time, errors.E) {
+	var newMtime time.Time
 	var ifModifiedSince string
 	if !mtime.IsZero() {
 		ifModifiedSince = strings.Replace(mtime.UTC().Format(time.RFC1123), "UTC", "GMT", 1)
 	}
 
-	req, err := http.NewRequestWithContext(ctx, "GET", url, http.NoBody)
-	if err != nil {
-		err = errors.WithMessagef(err, "could not create HTTP request for %s", url)
-
-		return
+	req, baseErr := http.NewRequestWithContext(ctx, "GET", url, http.NoBody)
+	if baseErr != nil {
+		return nil, newMtime, errors.WithMessagef(
+			baseErr,
+			"could not create HTTP request for %s",
+			url,
+		)
 	}
 
 	req.Header.Set("User-Agent", fmt.Sprintf("Searchix %s", config.Version))
@@ -54,21 +57,22 @@ func fetchFileIfNeeded(
 	if ifModifiedSince != "" {
 		req.Header.Set("If-Modified-Since", ifModifiedSince)
 	}
-	res, err := http.DefaultClient.Do(req)
-	if err != nil {
-		err = errors.WithMessagef(err, "could not make HTTP request to %s", url)
-
-		return
+	res, baseErr := http.DefaultClient.Do(req)
+	if baseErr != nil {
+		return nil, newMtime, errors.WithMessagef(baseErr, "could not make HTTP request to %s", url)
 	}
 
+	var body io.ReadCloser
+	var err errors.E
 	switch res.StatusCode {
 	case http.StatusNotModified:
 		newMtime = mtime
 
-		return
+		return nil, newMtime, nil
 	case http.StatusOK:
-		newMtime, err = time.Parse(time.RFC1123, res.Header.Get("Last-Modified"))
-		if err != nil {
+		var baseErr error
+		newMtime, baseErr = time.Parse(time.RFC1123, res.Header.Get("Last-Modified"))
+		if baseErr != nil {
 			log.Warn(
 				"could not parse Last-Modified header from response",
 				"value",
@@ -84,11 +88,11 @@ func fetchFileIfNeeded(
 		case "", "identity", "gzip":
 			body = res.Body
 		default:
-			err = fmt.Errorf("cannot handle a body with content-encoding %s", ce)
+			err = errors.Errorf("cannot handle a body with content-encoding %s", ce)
 		}
 	default:
-		err = fmt.Errorf("got response code %d, don't know what to do", res.StatusCode)
+		err = errors.Errorf("got response code %d, don't know what to do", res.StatusCode)
 	}
 
-	return
+	return body, newMtime, err
 }
diff --git a/internal/fetcher/main.go b/internal/fetcher/main.go
index ac40ead..c027fbb 100644
--- a/internal/fetcher/main.go
+++ b/internal/fetcher/main.go
@@ -8,7 +8,7 @@ import (
 	"go.alanpearce.eu/searchix/internal/index"
 	"go.alanpearce.eu/x/log"
 
-	"github.com/pkg/errors"
+	"gitlab.com/tozd/go/errors"
 )
 
 type FetchedFiles struct {
@@ -18,13 +18,13 @@ type FetchedFiles struct {
 }
 
 type Fetcher interface {
-	FetchIfNeeded(context.Context, *index.SourceMeta) (FetchedFiles, error)
+	FetchIfNeeded(context.Context, *index.SourceMeta) (*FetchedFiles, errors.E)
 }
 
 func New(
 	source *config.Source,
 	logger *log.Logger,
-) (fetcher Fetcher, err error) {
+) (fetcher Fetcher, err errors.E) {
 	switch source.Fetcher {
 	case config.ChannelNixpkgs:
 		fetcher, err = NewNixpkgsChannelFetcher(source, logger)
diff --git a/internal/fetcher/nixpkgs-channel.go b/internal/fetcher/nixpkgs-channel.go
index 6f8ca63..0424602 100644
--- a/internal/fetcher/nixpkgs-channel.go
+++ b/internal/fetcher/nixpkgs-channel.go
@@ -2,13 +2,12 @@ package fetcher
 
 import (
 	"context"
-	"fmt"
 	"net/url"
 
 	"go.alanpearce.eu/searchix/internal/config"
 	"go.alanpearce.eu/searchix/internal/index"
 
-	"github.com/pkg/errors"
+	"gitlab.com/tozd/go/errors"
 	"go.alanpearce.eu/x/log"
 )
 
@@ -17,7 +16,7 @@ type NixpkgsChannelFetcher struct {
 	Logger *log.Logger
 }
 
-func makeChannelURL(channel string, subPath string) (string, error) {
+func makeChannelURL(channel string, subPath string) (string, errors.E) {
 	url, err := url.JoinPath("https://channels.nixos.org/", channel, subPath)
 
 	return url, errors.WithMessagef(err, "error creating URL")
@@ -26,7 +25,7 @@ func makeChannelURL(channel string, subPath string) (string, error) {
 func NewNixpkgsChannelFetcher(
 	source *config.Source,
 	logger *log.Logger,
-) (*NixpkgsChannelFetcher, error) {
+) (*NixpkgsChannelFetcher, errors.E) {
 	switch source.Importer {
 	case config.Options, config.Packages:
 		return &NixpkgsChannelFetcher{
@@ -34,7 +33,7 @@ func NewNixpkgsChannelFetcher(
 			Logger: logger,
 		}, nil
 	default:
-		return nil, fmt.Errorf("unsupported importer type %s", source.Importer)
+		return nil, errors.Errorf("unsupported importer type %s", source.Importer)
 	}
 }
 
@@ -47,7 +46,7 @@ const (
 func (i *NixpkgsChannelFetcher) FetchIfNeeded(
 	ctx context.Context,
 	sourceMeta *index.SourceMeta,
-) (f FetchedFiles, err error) {
+) (f *FetchedFiles, err errors.E) {
 
 	filesToFetch := make([]string, 2)
 	filesToFetch[0] = revisionFilename