Skip to content

Commit 225f8bc

Browse files
authored
Merge pull request #6067 from fiam/alberto/show-token-error-details
fix: display error details on unexpected response status code errors
2 parents 2b69337 + d84b119 commit 225f8bc

File tree

4 files changed

+100
-39
lines changed

4 files changed

+100
-39
lines changed

exporter/containerimage/export.go

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/moby/buildkit/snapshot"
3030
"github.com/moby/buildkit/util/compression"
3131
"github.com/moby/buildkit/util/contentutil"
32+
"github.com/moby/buildkit/util/errutil"
3233
"github.com/moby/buildkit/util/leaseutil"
3334
"github.com/moby/buildkit/util/progress"
3435
"github.com/moby/buildkit/util/push"
@@ -358,10 +359,7 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
358359
if err != nil {
359360
var statusErr remoteserrors.ErrUnexpectedStatus
360361
if errors.As(err, &statusErr) {
361-
var dErr docker.Errors
362-
if err1 := json.Unmarshal(statusErr.Body, &dErr); err1 == nil && len(dErr) > 0 {
363-
err = &formattedDockerError{dErr: dErr}
364-
}
362+
err = errutil.WithDetails(err)
365363
}
366364
return nil, nil, errors.Wrapf(err, "failed to push %v", targetName)
367365
}
@@ -550,36 +548,3 @@ func (d *descriptorReference) Descriptor() ocispecs.Descriptor {
550548
func (d *descriptorReference) Release() error {
551549
return d.release(context.TODO())
552550
}
553-
554-
type formattedDockerError struct {
555-
dErr docker.Errors
556-
}
557-
558-
func (e *formattedDockerError) Error() string {
559-
format := func(err error) string {
560-
out := err.Error()
561-
var dErr docker.Error
562-
if errors.As(err, &dErr) {
563-
if v, ok := dErr.Detail.(string); ok && v != "" {
564-
out += " - " + v
565-
}
566-
}
567-
return out
568-
}
569-
switch len(e.dErr) {
570-
case 0:
571-
return "<nil>"
572-
case 1:
573-
return format(e.dErr[0])
574-
default:
575-
msg := "errors:\n"
576-
for _, err := range e.dErr {
577-
msg += format(err) + "\n"
578-
}
579-
return msg
580-
}
581-
}
582-
583-
func (e *formattedDockerError) Unwrap() error {
584-
return e.dErr
585-
}

session/auth/authprovider/authprovider.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
cleanhttp "github.com/hashicorp/go-cleanhttp"
2525
"github.com/moby/buildkit/session"
2626
"github.com/moby/buildkit/session/auth"
27+
"github.com/moby/buildkit/util/errutil"
2728
"github.com/moby/buildkit/util/progress/progresswriter"
2829
"github.com/moby/buildkit/util/tracing"
2930
"github.com/pkg/errors"
@@ -136,7 +137,7 @@ func (ap *authProvider) FetchToken(ctx context.Context, req *auth.FetchTokenRequ
136137
return err
137138
}
138139
defer func() {
139-
err = errors.Wrap(err, "failed to fetch oauth token")
140+
err = errors.Wrap(errutil.WithDetails(err), "failed to fetch oauth token")
140141
}()
141142
ap.mu.Lock()
142143
name := fmt.Sprintf("[auth] %v token for %s", strings.Join(trimScopePrefix(req.Scopes), " "), req.Host)

util/errutil/errutil.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package errutil
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"fmt"
7+
8+
"github.com/containerd/containerd/v2/core/remotes/docker"
9+
remoteserrors "github.com/containerd/containerd/v2/core/remotes/errors"
10+
)
11+
12+
const (
13+
maxPrintedBodySize = 256
14+
)
15+
16+
func WithDetails(err error) error {
17+
if err == nil {
18+
return nil
19+
}
20+
var errStatus remoteserrors.ErrUnexpectedStatus
21+
if errors.As(err, &errStatus) {
22+
var dErr docker.Errors
23+
if err1 := json.Unmarshal(errStatus.Body, &dErr); err1 == nil && len(dErr) > 0 {
24+
return &formattedDockerError{dErr: dErr}
25+
}
26+
27+
return verboseUnexpectedStatusError{ErrUnexpectedStatus: errStatus}
28+
}
29+
return err
30+
}
31+
32+
type verboseUnexpectedStatusError struct {
33+
remoteserrors.ErrUnexpectedStatus
34+
}
35+
36+
func (e verboseUnexpectedStatusError) Unwrap() error {
37+
return e.ErrUnexpectedStatus
38+
}
39+
40+
func (e verboseUnexpectedStatusError) Error() string {
41+
if len(e.Body) == 0 {
42+
return e.ErrUnexpectedStatus.Error()
43+
}
44+
var details string
45+
46+
var errDetails struct {
47+
Details string `json:"details"`
48+
}
49+
50+
if err := json.Unmarshal(e.Body, &errDetails); err == nil && errDetails.Details != "" {
51+
details = errDetails.Details
52+
} else {
53+
if len(e.Body) > maxPrintedBodySize {
54+
details = string(e.Body[:maxPrintedBodySize]) + fmt.Sprintf("... (%d bytes truncated)", len(e.Body)-maxPrintedBodySize)
55+
} else {
56+
details = string(e.Body)
57+
}
58+
}
59+
60+
return fmt.Sprintf("%s: %s", e.ErrUnexpectedStatus.Error(), details)
61+
}
62+
63+
type formattedDockerError struct {
64+
dErr docker.Errors
65+
}
66+
67+
func (e *formattedDockerError) Error() string {
68+
format := func(err error) string {
69+
out := err.Error()
70+
var dErr docker.Error
71+
if errors.As(err, &dErr) {
72+
if v, ok := dErr.Detail.(string); ok && v != "" {
73+
out += " - " + v
74+
}
75+
}
76+
return out
77+
}
78+
switch len(e.dErr) {
79+
case 0:
80+
return "<nil>"
81+
case 1:
82+
return format(e.dErr[0])
83+
default:
84+
msg := "errors:\n"
85+
for _, err := range e.dErr {
86+
msg += format(err) + "\n"
87+
}
88+
return msg
89+
}
90+
}
91+
92+
func (e *formattedDockerError) Unwrap() error {
93+
return e.dErr
94+
}

util/resolver/authorizer.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/moby/buildkit/session"
1919
sessionauth "github.com/moby/buildkit/session/auth"
2020
"github.com/moby/buildkit/util/bklog"
21+
"github.com/moby/buildkit/util/errutil"
2122
"github.com/moby/buildkit/util/flightcontrol"
2223
"github.com/moby/buildkit/version"
2324
"github.com/pkg/errors"
@@ -367,7 +368,7 @@ func (ah *authHandler) fetchToken(ctx context.Context, sm *session.Manager, g se
367368
// fetch token for the resource scope
368369
if to.Secret != "" {
369370
defer func() {
370-
err = errors.Wrap(err, "failed to fetch oauth token")
371+
err = errors.Wrap(errutil.WithDetails(err), "failed to fetch oauth token")
371372
}()
372373
// try GET first because Docker Hub does not support POST
373374
// switch once support has landed

0 commit comments

Comments
 (0)