Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved error handling in Websocket server #229

Merged
merged 23 commits into from
Apr 30, 2018

Conversation

blondejamtart
Copy link
Contributor

Added return error messages to client following errors in websocket comms
Also fixed test requirements.

Added return error messages to client following errors in websocket comms
Also fixed test requirements.
Tweaked error messages for various components called in WebsocketHandler
to improve readability and added to unit tests
@@ -187,7 +187,9 @@ def _handle_get(self, request):
# type: (Get) -> CallbackResponses
"""Called with the lock taken"""
data = self._block
for endpoint in request.path[1:]:

for point in range(1, len(request.path)):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I suggest:

for i, endpoint in enumerate(request.path[1:]):

@@ -76,9 +76,12 @@ class PathRequest(Request):
def __init__(self, id=0, path=None):
# type: (AId, UPath) -> None
super(PathRequest, self).__init__(id)
if path:
assert isinstance(path, list), "Path must be given as a list"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(list, tuple)

@@ -108,7 +112,7 @@ def deserialize_object(ob, type_check=None):
ob = subclass.from_dict(ob)
if type_check is not None:
assert isinstance(ob, type_check), \
"Expected %s, got %r" % (type_check, ob)
"Expected %s, got %r" % (type_check, subclass)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type(ob)

try:
inst = cls(**filtered)
except TypeError as e:
raise TypeError("%s method %s" % (cls.typeid, str(e)))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"%s(**%s) raised error: %s" %(type(cls), filtered, e)

try:
typeid = d["typeid"]
except KeyError:
raise KeyError("typeid field not present in JSON message")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include the dict?

subclass = cls._subcls_lookup[typeid]
return subclass
except KeyError as e:
raise KeyError('%s not a valid malcolm message subclass' % str(e))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe do cls._subcls_lookup.get(typeid, None)

if subclass is None:
raise KeyError('%s not a valid typeid" % typeid)

is not a valid typeid

@gen.coroutine
def send_bad_json_message(self, error_type):
# 0 = no ID, 1 = bad typeID, 2 = no typeID, 3 = bad path, 4 = no path
req = [dict(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move these to where they are called from please

@blondejamtart
Copy link
Contributor Author

One test is failing on Travis but passes on my local machine; appears to be mostly to do with how I've included a stringified dict object in one of the error messages (raised in serializable.py line 213), since it causes inconsistent quotation marks and capitalisation. Need a more robust/reliable way to send the dict info (or just drop it from the message?)

conn.write_message(json.dumps(req))
resp = yield conn.read_message()
resp = json.loads(resp)
self.result.put(resp)
conn.close()

@gen.coroutine
def send_non_JSON_message(self):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you merge this with the previous function please. I suggest

def send_message(self, req, json_convert=True):

assert isinstance(o, OrderedDict), "didn't return OrderedDict"
return o
except Exception as e:
raise ValueError("Error decoding JSON object (%s)" % str(e))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 space indent please

assert resp == dict(
typeid="malcolm:core/Error:1.0",
id=-1,
message="KeyError: 'id field not present in JSON message'"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get rid of these extra quotes we need to change serialize_hook in serializable.py to return:

"%s: %s" % (type(o).__name__, o.message)

instead of

"%s: %s" % (type(o).__name__, o)

assert resp == dict(
typeid="malcolm:core/Error:1.0",
id=0,
message='''KeyError: "typeid field not present in dictionary ( d = OrderedDict([(u\'path\',''' +

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change it to just print the keys rather than the dict

Bryan Robert Tester and others added 17 commits April 27, 2018 10:57
Temporarily disabled some tests which were being troublesome on Travis
Gone back to str(error) instead of error.message for compatibility reasons,
also implemented "FieldError" class to replace KeyError
for better behaviour with the above
Added different expected results for python3 (with version check)
for some WebsocketHandler error cases
Attempt to correct inconsistent behaviour of OrderedDict.keys()
between python versions
@@ -6,7 +6,7 @@
from enum import Enum

from malcolm.compat import OrderedDict

from malcolm.core.errors import FieldError

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from .errors import FieldError

try:
typeid = d["typeid"]
except KeyError:
raise FieldError("typeid field not present in dictionary ( d.keys() = %s )" % list(dict(d).keys()))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list(d)

@thomascobb thomascobb merged commit 79db61c into annotypes Apr 30, 2018
@thomascobb thomascobb deleted the WebSocket-ErrorReporting branch April 30, 2018 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants