From c43feb1f5aa0c14dc1c818d227a42d5770777c18 Mon Sep 17 00:00:00 2001 From: John Beisley Date: Sat, 26 Mar 2022 08:33:56 +0000 Subject: [PATCH] Add ErrFault error marker. --- v2alpha/soap/envelope/envelope.go | 8 ++++++ v2alpha/soap/envelope/envelope_test.go | 36 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/v2alpha/soap/envelope/envelope.go b/v2alpha/soap/envelope/envelope.go index dbd6934..05e60ed 100644 --- a/v2alpha/soap/envelope/envelope.go +++ b/v2alpha/soap/envelope/envelope.go @@ -3,10 +3,14 @@ package envelope import ( "encoding/xml" + "errors" "fmt" "io" ) +// ErrFault can be used as a target with errors.Is. +var ErrFault error = errors.New("xml fault") + // FaultDetail carries XML-encoded application-specific Fault details. type FaultDetail struct { Raw []byte `xml:",innerxml"` @@ -24,6 +28,10 @@ func (fe *Fault) Error() string { return fmt.Sprintf("SOAP fault code=%s: %s", fe.Code, fe.String) } +func (fe *Fault) Is(target error) bool { + return target == ErrFault +} + // Various "constant" bytes used in the written envelope. var ( envOpen = []byte(xml.Header + ``) diff --git a/v2alpha/soap/envelope/envelope_test.go b/v2alpha/soap/envelope/envelope_test.go index 550faa6..b2fa27d 100644 --- a/v2alpha/soap/envelope/envelope_test.go +++ b/v2alpha/soap/envelope/envelope_test.go @@ -3,6 +3,9 @@ package envelope import ( "bytes" "encoding/xml" + "errors" + "fmt" + "io" "reflect" "testing" ) @@ -76,3 +79,36 @@ s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> t.Errorf("want %+v, got %+v", wantFault, gotFault) } } + +func TestFault(t *testing.T) { + tests := []struct { + name string + err error + wantIs bool + }{ + {"plain fault", &Fault{Code: "code"}, true}, + {"wrapped fault", fmt.Errorf("wrapper: %w", &Fault{Code: "code"}), true}, + {"other error", io.EOF, false}, + } + + for _, test := range tests { + test := test // copy for closure + t.Run(test.name, func(t *testing.T) { + if got, want := errors.Is(test.err, ErrFault), test.wantIs; got != want { + t.Errorf("got errors.Is(%v, ErrFault)=>%t, want %t", test.err, got, want) + } + if !test.wantIs { + return + } + + var fault *Fault + if got, want := errors.As(test.err, &fault), true; got != want { + t.Fatalf("got errors.As(%v, ...)=>%t, want %t", test.err, got, want) + } + + if got, want := fault.Code, "code"; got != want { + t.Errorf("got fault.Code=%q, want %q", got, want) + } + }) + } +}