diff --git a/aioupnp/serialization/soap.py b/aioupnp/serialization/soap.py
index 9ebc07a..9ee2c08 100644
--- a/aioupnp/serialization/soap.py
+++ b/aioupnp/serialization/soap.py
@@ -1,5 +1,6 @@
import re
import typing
+import json
from aioupnp.util import flatten_keys
from aioupnp.fault import UPnPError
from aioupnp.constants import XML_VERSION, ENVELOPE, BODY, FAULT, CONTROL
@@ -54,7 +55,10 @@ def deserialize_soap_post_response(response: bytes, method: str,
fault: typing.Dict[str, typing.Dict[str, typing.Dict[str, str]]] = flatten_keys(
response_body[FAULT], "{%s}" % CONTROL
)
- raise UPnPError(fault['detail']['UPnPError']['errorDescription'])
+ try:
+ raise UPnPError(fault['detail']['UPnPError']['errorDescription'])
+ except (KeyError, TypeError, ValueError):
+ raise UPnPError(f"Failed to decode error response: {json.dumps(fault)}")
response_key = None
for key in response_body:
if method in key:
diff --git a/tests/serialization/test_soap.py b/tests/serialization/test_soap.py
index ea3cf04..0105498 100644
--- a/tests/serialization/test_soap.py
+++ b/tests/serialization/test_soap.py
@@ -58,6 +58,16 @@ class TestSOAPSerialization(unittest.TestCase):
b"\r\n" \
b"\n\n\t\n\t\t\n\t\t\ts:Client\n\t\t\tUPnPError\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t713\n\t\t\t\t\tSpecifiedArrayIndexInvalid\n\t\t\t\t\n\t\t\t\n\t\t\n\t\n\n"
+ error_response_no_description = b"HTTP/1.1 500 Internal Server Error\r\n" \
+ b"Server: WebServer\r\n" \
+ b"Date: Thu, 11 Oct 2018 22:16:17 GMT\r\n" \
+ b"Connection: close\r\n" \
+ b"CONTENT-TYPE: text/xml; charset=\"utf-8\"\r\n" \
+ b"CONTENT-LENGTH: 429 \r\n" \
+ b"EXT:\r\n" \
+ b"\r\n" \
+ b"\n\n\t\n\t\t\n\t\t\ts:Client\n\t\t\tUPnPError\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t713\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\n\n"
+
def test_serialize_post(self):
self.assertEqual(serialize_soap_post(
self.method, self.param_names, self.st, self.gateway_address, self.path, **self.kwargs
@@ -94,3 +104,13 @@ class TestSOAPSerialization(unittest.TestCase):
raised = True
self.assertTrue(str(err) == 'SpecifiedArrayIndexInvalid')
self.assertTrue(raised)
+
+ def test_raise_from_error_response_without_error_description(self):
+ raised = False
+ expected = 'Failed to decode error response: {"faultcode": "s:Client", "faultstring": "UPnPError", "detail": {"UPnPError": {"errorCode": "713"}}}'
+ try:
+ deserialize_soap_post_response(self.error_response_no_description, self.method, service_id=self.st.decode())
+ except UPnPError as err:
+ raised = True
+ self.assertTrue(str(err) == expected)
+ self.assertTrue(raised)