diff --git a/soap/soap.go b/soap/soap.go index 0d7a758..689f2a4 100644 --- a/soap/soap.go +++ b/soap/soap.go @@ -194,9 +194,13 @@ type soapBody struct { // SOAPFaultError implements error, and contains SOAP fault information. type SOAPFaultError struct { - FaultCode string `xml:"faultCode"` - FaultString string `xml:"faultString"` + FaultCode string `xml:"faultcode"` + FaultString string `xml:"faultstring"` Detail struct { + UPnPError struct { + Errorcode int `xml:"errorCode"` + ErrorDescription string `xml:"errorDescription"` + } `xml:"UPnPError"` Raw []byte `xml:",innerxml"` } `xml:"detail"` } diff --git a/soap/soap_test.go b/soap/soap_test.go index 889a009..08de9fa 100644 --- a/soap/soap_test.go +++ b/soap/soap_test.go @@ -6,6 +6,7 @@ import ( "net/http" "net/url" "reflect" + "strings" "testing" ) @@ -87,6 +88,74 @@ func TestActionInputs(t *testing.T) { } } +func TestUPnPError(t *testing.T) { + t.Parallel() + url, err := url.Parse("http://example.com/soap") + if err != nil { + t.Fatal(err) + } + body := ` + + + + s:Client + UPnPError + + + 725 + OnlyPermanentLeasesSupported + + + + + ` + rt := &capturingRoundTripper{ + resp: &http.Response{ + StatusCode: 500, + ContentLength: int64(len(body)), + Body: ioutil.NopCloser(bytes.NewBufferString(body)), + }, + } + client := SOAPClient{ + EndpointURL: *url, + HTTPClient: http.Client{ + Transport: rt, + }, + } + + err = client.PerformAction("mynamespace", "myaction", nil, nil) + if err == nil { + t.Fatal("expected error, got nil") + } + if testing.Verbose() { + t.Logf("%+v\n", err) + } + soapErr, ok := err.(*SOAPFaultError) + if !ok { + t.Fatal("expected *SOAPFaultError") + } + if soapErr.FaultCode != "s:Client" { + t.Fatalf("unexpected FaultCode: %s", soapErr.FaultCode) + } + if soapErr.FaultString != "UPnPError" { + t.Fatalf("unexpected FaultString: %s", soapErr.FaultString) + } + if soapErr.Detail.UPnPError.Errorcode != 725 { + t.Fatalf("unexpected UPnPError Errorcode: %d", soapErr.Detail.UPnPError.Errorcode) + } + if soapErr.Detail.UPnPError.ErrorDescription != "OnlyPermanentLeasesSupported" { + t.Fatalf("unexpected UPnPError ErrorDescription: %s", + soapErr.Detail.UPnPError.ErrorDescription) + } + if !strings.EqualFold(string(soapErr.Detail.Raw), ` + + 725 + OnlyPermanentLeasesSupported + +`) { + t.Fatalf("unexpected Detail.Raw, got:\n%s", string(soapErr.Detail.Raw)) + } +} func TestEscapeXMLText(t *testing.T) { t.Parallel()