Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions varlink/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ def new(cls, message, namespaced=False):
elif message["error"] == "org.varlink.service.MethodNotImplemented":
return MethodNotImplemented.new(message, namespaced)

elif message["error"] == "org.varlink.service.MethodNotFound":
return MethodNotFound.new(message, namespaced)

else:
return cls(message, namespaced)

Expand All @@ -45,15 +48,19 @@ def error(self):
"""returns the exception varlink error name"""
return self.args[0].get("error")

def parameters(self, namespaced=False):
"""returns the exception varlink error parameters"""
@staticmethod
def message_parameters(message, namespaced=False):
if namespaced:
return json.loads(
json.dumps(self.args[0]["parameters"]),
json.dumps(message["parameters"]),
object_hook=lambda d: SimpleNamespace(**d),
)
else:
return self.args[0].get("parameters")
return message.get("parameters")

def parameters(self, namespaced=False):
"""returns the exception varlink error parameters"""
return self.message_parameters(self.args[0], namespaced)

def as_dict(self):
return self.args[0]
Expand All @@ -64,9 +71,11 @@ class InterfaceNotFound(VarlinkError):

@classmethod
def new(cls, message, namespaced=False):
return cls(
namespaced and message["parameters"].interface or message["parameters"].get("interface", None)
)
parameters = cls.message_parameters(message, namespaced)
if parameters is None:
# Back-compatibility error
raise KeyError("parameters")
return cls(parameters.interface if namespaced else parameters.get("interface", None))

def __init__(self, interface):
VarlinkError.__init__(
Expand All @@ -83,7 +92,8 @@ class MethodNotFound(VarlinkError):

@classmethod
def new(cls, message, namespaced=False):
return cls(namespaced and message["parameters"].method or message["parameters"].get("method", None))
parameters = cls.message_parameters(message, namespaced)
return cls(namespaced and parameters.method or parameters.get("method", None))

def __init__(self, method):
VarlinkError.__init__(
Expand All @@ -100,7 +110,8 @@ class MethodNotImplemented(VarlinkError):

@classmethod
def new(cls, message, namespaced=False):
return cls(namespaced and message["parameters"].method or message["parameters"].get("method", None))
parameters = cls.message_parameters(message, namespaced)
return cls(namespaced and parameters.method or parameters.get("method", None))

def __init__(self, method):
VarlinkError.__init__(
Expand All @@ -117,9 +128,8 @@ class InvalidParameter(VarlinkError):

@classmethod
def new(cls, message, namespaced=False):
return cls(
namespaced and message["parameters"].parameter or message["parameters"].get("parameter", None)
)
parameters = cls.message_parameters(message, namespaced)
return cls(namespaced and parameters.parameter or parameters.get("parameter", None))

def __init__(self, name):
VarlinkError.__init__(
Expand Down
34 changes: 34 additions & 0 deletions varlink/tests/test_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import json
import unittest

import varlink


class OneMessageClientHandler(varlink.ClientInterfaceHandler):
def __init__(self, interface, namespaced, next_message):
# No interface but we do not use them
super().__init__(interface, namespaced)
self.next_message = next_message

def _next_message(self):
yield self.next_message


class TestError(unittest.TestCase):
def test_pack_unpack(self):
dummy_if = varlink.Interface("interface org.example.dummy")
for error in [
varlink.InterfaceNotFound("org.varlink.notfound"),
varlink.MethodNotFound("Method"),
varlink.MethodNotImplemented("Abstract"),
varlink.InvalidParameter("Struct.param"),
]:
for namespaced in (True, False):
with self.subTest(error=error, namespaced=namespaced):
# encode error
encoded = json.dumps(error, cls=varlink.VarlinkEncoder)

# Emulates the client receiving an error
handler = OneMessageClientHandler(dummy_if, namespaced, encoded)
with self.assertRaises(error.__class__):
handler._next_varlink_message()