@@ -2,10 +2,11 @@ package grpcerrors_test
22
33import (
44 "context"
5+ stderrors "errors"
56 "fmt"
6- "strings"
77 "testing"
88
9+ "github.com/moby/buildkit/solver/errdefs"
910 "github.com/moby/buildkit/util/grpcerrors"
1011 "github.com/pkg/errors"
1112 "github.com/stretchr/testify/assert"
@@ -65,6 +66,50 @@ func TestFromGRPCPreserveUnknownTypes(t *testing.T) {
6566 reDecodedErr := grpcerrors .FromGRPC (reEncodedErr )
6667 assertErrorProperties (t , reDecodedErr )
6768 })
69+
70+ }
71+
72+ func TestFromGRPCPreserveUnknownTypes_WithJoin (t * testing.T ) {
73+ t .Parallel ()
74+ const (
75+ unknownType = "type.googleapis.com/unknown.Type"
76+ unknownValue = "unknown value"
77+
78+ errMessage = "something failed"
79+ errCode = codes .Internal
80+ )
81+ raw := & anypb.Any {
82+ TypeUrl : unknownType ,
83+ Value : []byte (unknownValue ),
84+ }
85+
86+ pb := & spb.Status {
87+ Code : int32 (errCode ),
88+ Message : errMessage ,
89+ Details : []* anypb.Any {raw },
90+ }
91+
92+ // Decode the original status into a Go error, then join it with a typed error
93+ decodedErr := grpcerrors .FromGRPC (status .FromProto (pb ).Err ())
94+ // Create a typed error (errdefs.Solve) and wrap a base error with it
95+ typed := & errdefs.Solve {InputIDs : []string {"typed-input" }}
96+ typedErr := typed .WrapError (stderrors .New ("typed-base" ))
97+ joined := stderrors .Join (decodedErr , typedErr )
98+
99+ // Re-encode and decode the joined error and ensure the unknown detail is preserved
100+ reEncoded := grpcerrors .ToGRPC (context .TODO (), joined )
101+ reDecoded := grpcerrors .FromGRPC (reEncoded )
102+
103+ require .Error (t , reDecoded )
104+
105+ // Ensure the typed error was preserved by finding the SolveError in the decoded error
106+ var se * errdefs.SolveError
107+ require .True (t , stderrors .As (reDecoded , & se ))
108+ require .NotNil (t , se )
109+ assert .Equal (t , []string {"typed-input" }, se .Solve .InputIDs )
110+
111+ // And ensure the original unknown detail is still present
112+ assert .ErrorContains (t , reDecoded , errMessage )
68113}
69114
70115func TestToGRPCMessage (t * testing.T ) {
@@ -79,10 +124,15 @@ func TestToGRPCMessage(t *testing.T) {
79124 t .Parallel ()
80125 err := errors .New ("something" )
81126 wrapped := errors .Wrap (grpcerrors .ToGRPC (context .TODO (), err ), "extra context" )
127+
128+ anotherErr := errors .New ("another error" )
129+ joined := stderrors .Join (wrapped , anotherErr )
130+
82131 // Check that wrapped.Error() starts with "extra context"
83- assert .True (t , strings .HasPrefix (wrapped .Error (), "extra context" ), "expected wrapped error to start with 'extra context'" )
84- encoded := grpcerrors .ToGRPC (context .TODO (), wrapped )
132+ encoded := grpcerrors .ToGRPC (context .TODO (), joined )
85133 decoded := grpcerrors .FromGRPC (encoded )
86- assert .Equal (t , wrapped .Error (), decoded .Error ())
134+
135+ assert .ErrorContains (t , decoded , wrapped .Error ())
136+ assert .ErrorContains (t , decoded , anotherErr .Error ())
87137 })
88138}
0 commit comments