Skip to content

Commit 6620e89

Browse files
authored
Merge pull request #81 from wlynch/error-suggestions
Add error suggestions
2 parents b14dddc + c8497c1 commit 6620e89

1 file changed

Lines changed: 32 additions & 50 deletions

File tree

internal/explore/explore.go

Lines changed: 32 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"compress/gzip"
88
"encoding/base64"
99
"encoding/json"
10+
"errors"
1011
"fmt"
1112
"html"
1213
"io"
@@ -170,11 +171,41 @@ func (h *handler) errHandler(hfe HandleFuncE) http.HandlerFunc {
170171
if err := h.maybeOauthErr(w, r, err); err != nil {
171172
log.Printf("%s: %v", r.URL.Path, err)
172173
fmt.Fprintf(w, "failed: %s", html.EscapeString(err.Error()))
174+
175+
var serr *ErrorSuggestion
176+
if errors.As(err, &serr) {
177+
fmt.Fprintf(w, "<p><i>suggestion: %s</i></p>", serr.Suggestion())
178+
}
173179
}
174180
}
175181
}
176182
}
177183

184+
// ErrorSuggestion wraps an upstream error with a server-provided suggestion for the user.
185+
type ErrorSuggestion struct {
186+
err error
187+
suggest string
188+
}
189+
190+
func NewErrorSuggestion(err error, suggest string) *ErrorSuggestion {
191+
return &ErrorSuggestion{
192+
err: err,
193+
suggest: suggest,
194+
}
195+
}
196+
197+
func (e *ErrorSuggestion) Error() string {
198+
return e.err.Error()
199+
}
200+
201+
func (e *ErrorSuggestion) Unwrap() error {
202+
return e.err
203+
}
204+
205+
func (e *ErrorSuggestion) Suggestion() string {
206+
return e.suggest
207+
}
208+
178209
func (h *handler) renderResponse(w http.ResponseWriter, r *http.Request) error {
179210
qs := r.URL.Query()
180211

@@ -208,10 +239,6 @@ func (h *handler) renderRepo(w http.ResponseWriter, r *http.Request, repo string
208239
return err
209240
}
210241

211-
if repo == "cgr.dev/chainguard" {
212-
return h.renderChainguardRepo(w, r, repo)
213-
}
214-
215242
reg := ref.RegistryStr()
216243
googleRepo := reg == "registry.k8s.io" || reg == "mirror.gcr.io" || (isGoogle(reg) && ref.RepositoryStr() != "")
217244
hubRepo := (strings.HasPrefix(repo, "index.docker.io") || strings.HasPrefix(repo, "docker.io")) && strings.Count(repo, "/") == 1
@@ -263,7 +290,7 @@ func (h *handler) renderRepo(w http.ResponseWriter, r *http.Request, repo string
263290
tags, err := h.listTags(w, r, ref, repo)
264291
if err != nil {
265292
if tags == nil {
266-
return err
293+
return NewErrorSuggestion(err, fmt.Sprintf(`try <a href="/?repo=%s">catalog</a>?`, ref.RegistryStr()))
267294
}
268295

269296
// Sometimes we time out (or other issues), render whatever we got.
@@ -282,51 +309,6 @@ func (h *handler) renderRepo(w http.ResponseWriter, r *http.Request, repo string
282309
return nil
283310
}
284311

285-
func (h *handler) renderChainguardRepo(w http.ResponseWriter, r *http.Request, repo string) error {
286-
// ls ../../chainguard-images/images/images | jq -Rn '{"child": [inputs] }' > cmd/oci/kodata/chainguard.json
287-
fn := filepath.Join(os.Getenv("KO_DATA_PATH"), "chainguard.json")
288-
b, err := os.ReadFile(fn)
289-
if err != nil {
290-
return err
291-
}
292-
293-
if err := headerTmpl.Execute(w, TitleData{repo}); err != nil {
294-
return err
295-
}
296-
header := HeaderData{
297-
Repo: repo,
298-
Reference: repo,
299-
JQ: "chainctl img repo ls | jq . # kind of...",
300-
}
301-
if strings.Contains(repo, "/") {
302-
base := path.Base(repo)
303-
dir := path.Dir(strings.TrimRight(repo, "/"))
304-
if base != "." && dir != "." {
305-
header.Up = &RepoParent{
306-
Parent: dir,
307-
Child: base,
308-
Separator: "/",
309-
}
310-
}
311-
}
312-
if err := bodyTmpl.Execute(w, header); err != nil {
313-
return err
314-
}
315-
316-
output := &jsonOutputter{
317-
w: w,
318-
u: r.URL,
319-
fresh: []bool{},
320-
repo: repo,
321-
}
322-
if err := renderJSON(output, b); err != nil {
323-
return err
324-
}
325-
326-
fmt.Fprintf(w, footer)
327-
return nil
328-
}
329-
330312
func (h *handler) renderGoogleRepo(w http.ResponseWriter, r *http.Request, repo string) error {
331313
ref, err := name.NewRepository(repo)
332314
if err != nil {

0 commit comments

Comments
 (0)