diff --git a/pkg/depresolver/githubreleaseasset.go b/pkg/depresolver/githubreleaseasset.go index 5f939ac..756c4af 100644 --- a/pkg/depresolver/githubreleaseasset.go +++ b/pkg/depresolver/githubreleaseasset.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "io" - "log" "net/http" "net/url" "os" @@ -211,9 +210,10 @@ func (a *githubReleaseAsset) getFile(dst string, owner, repo string, assetID int return fmt.Errorf("mkdir %s: %w", dir, err) } - req, err := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/assets/%d", owner, repo, assetID), nil) + reqURL := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/assets/%d", owner, repo, assetID) + req, err := http.NewRequest("GET", reqURL, nil) if err != nil { - log.Fatal(err) + return err } req.Header = make(http.Header) if gt := os.Getenv("GITHUB_TOKEN"); gt != "" { @@ -227,6 +227,10 @@ func (a *githubReleaseAsset) getFile(dst string, owner, repo string, assetID int } defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return fmt.Errorf("GET %s: %s", reqURL, res.Status) + } + f, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE, os.FileMode(0666)) if err != nil { return fmt.Errorf("open file %s: %w", dst, err) diff --git a/pkg/maputil/maputil.go b/pkg/maputil/maputil.go index ab18147..739be0f 100644 --- a/pkg/maputil/maputil.go +++ b/pkg/maputil/maputil.go @@ -12,7 +12,7 @@ func CastKeysToStrings(s interface{}) (map[string]interface{}, error) { case string: str_k = typed_k default: - return nil, fmt.Errorf("unexpected type of key in map: expected string, got %T: value=%v, map=%v", typed_k, typed_k, src) + return nil, fmt.Errorf("unexpected type of key in map: expected string, got %T: value=%v", typed_k, typed_k) } casted_v, err := recursivelyStringifyMapKey(v) @@ -32,7 +32,7 @@ func CastKeysToStrings(s interface{}) (map[string]interface{}, error) { new[k] = casted_v } default: - return nil, fmt.Errorf("unexpected type: value=%v, type=%T", src, src) + return nil, fmt.Errorf("unexpected type: type=%T", src) } return new, nil } diff --git a/pkg/releasetracker/tracker.go b/pkg/releasetracker/tracker.go index 8b36a3f..bab940e 100644 --- a/pkg/releasetracker/tracker.go +++ b/pkg/releasetracker/tracker.go @@ -154,6 +154,34 @@ func debug(msg string, v ...interface{}) { } } +// summarizeValue returns a short description of a value suitable for error messages, +// avoiding dumping entire API response objects. +func summarizeValue(v interface{}) string { + switch typed := v.(type) { + case []interface{}: + return fmt.Sprintf("[]interface{} (%d items)", len(typed)) + case map[string]interface{}: + keys := make([]string, 0, len(typed)) + for k := range typed { + keys = append(keys, k) + } + if len(keys) > 5 { + return fmt.Sprintf("map[string]interface{} (%d keys, including %v, ...)", len(keys), keys[:5]) + } + return fmt.Sprintf("map[string]interface{} (keys: %v)", keys) + case map[interface{}]interface{}: + return fmt.Sprintf("map[interface{}]interface{} (%d keys)", len(typed)) + case nil: + return "" + default: + s := fmt.Sprintf("%v", v) + if len(s) > 200 { + return s[:200] + "..." + } + return s + } +} + func (p *Tracker) Latest(constraint string) (*Release, error) { all, err := p.GetReleases() if err != nil { @@ -528,7 +556,7 @@ func (p *Tracker) extractObjects(tmp interface{}, objPath, verPath, metaKey stri got, err := jsonpath.Get(objPath, v) if err != nil { - return nil, fmt.Errorf("unable to lookup %q in object %v: %v", objPath, v, err) + return nil, fmt.Errorf("unable to lookup %q in object (%s): %v", objPath, summarizeValue(v), err) } var rs []*Release @@ -542,7 +570,7 @@ func (p *Tracker) extractObjects(tmp interface{}, objPath, verPath, metaKey stri for _, obj := range typed { raw, err := jsonpath.Get(verPath, obj) if err != nil { - return nil, fmt.Errorf("unable to get version at %s from %v: %v", verPath, obj, err) + return nil, fmt.Errorf("unable to get version at %s from %s: %v", verPath, summarizeValue(obj), err) } s, ok := raw.(string) @@ -584,7 +612,7 @@ func (p *Tracker) extractObjects(tmp interface{}, objPath, verPath, metaKey stri func (p *Tracker) extractVersions(tmp interface{}, jpath string) ([]*Release, error) { vs, err := p.extractVersionStrings(tmp, jpath) if err != nil { - return nil, fmt.Errorf("unalble to extract versions at %s from %v: %v", jpath, tmp, err) + return nil, fmt.Errorf("unable to extract versions at %s from %s: %v", jpath, summarizeValue(tmp), err) } return p.versionsToReleases(vs) @@ -635,11 +663,11 @@ func (p *Tracker) extractVersionStrings(tmp interface{}, jpath string) ([]string case map[string]interface{}: raw = append(raw, typed) default: - return nil, fmt.Errorf("unexpected type of result from jsonpath: \"%s\": %v", jpath, typed) + return nil, fmt.Errorf("unexpected type of result from jsonpath %q: got %T", jpath, typed) } if len(raw) == 0 { - return nil, fmt.Errorf("jsonpath: \"%s\": returned nothing: %v", jpath, v) + return nil, fmt.Errorf("jsonpath %q: returned nothing from %s", jpath, summarizeValue(v)) } vs := []string{} @@ -656,7 +684,7 @@ func (p *Tracker) extractVersionStrings(tmp interface{}, jpath string) ([]string case string: vs = append(vs, typed) default: - return nil, fmt.Errorf("jsonpath: unexpected type of result: %T=%v", typed, typed) + return nil, fmt.Errorf("jsonpath: unexpected type of result: %T (%s)", typed, summarizeValue(typed)) } } diff --git a/pkg/vhttpget/vhttpget.go b/pkg/vhttpget/vhttpget.go index 4fa2382..4c5de0b 100644 --- a/pkg/vhttpget/vhttpget.go +++ b/pkg/vhttpget/vhttpget.go @@ -43,7 +43,21 @@ func New() Getter { } res, err := http.DefaultClient.Do(req) - return res.Body, err + if err != nil { + return nil, err + } + + if res.StatusCode < 200 || res.StatusCode >= 300 { + defer res.Body.Close() + body, _ := ioutil.ReadAll(io.LimitReader(res.Body, 512)) + snippet := string(body) + if len(snippet) > 0 { + return nil, fmt.Errorf("GET %s: %s: %s", url, res.Status, snippet) + } + return nil, fmt.Errorf("GET %s: %s", url, res.Status) + } + + return res.Body, nil }, } }