From 19a293cba5312444f17888901fefab9f65bb31a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Tue, 14 Mar 2017 16:23:03 -0400 Subject: [PATCH 1/2] Allow remote module to transmit exception to Ubersmith --- tests/test_api.py | 22 ++++++++++++++++++++++ ubersmith_remote_module_server/api.py | 8 ++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index fc5ac42..22a5596 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -66,6 +66,26 @@ def test_execute_method_returns_string(self): self.router.invoke_method.assert_called_with(module=self.module2, method='remote_method', params=[], env={'variable1': 'value1'}, callback={}) assert_that(json.loads(output.data.decode(output.charset)), is_('simple string')) + assert_that(output.status_code, is_(200)) + + def test_execute_method_raise_an_exception(self): + self.router.invoke_method.side_effect = Exception('Some Error') + output = self.api_client.post(self.generate_module_path('module2'), + headers={'Content-Type': 'application/json'}, + data=json.dumps( + { + "method": "remote_method", + "params": [], + "env": { + "variable1": "value1" + }, + "callback": {} + } + )) + + self.router.invoke_method.assert_called_with(module=self.module2, method='remote_method', params=[], env={'variable1': 'value1'}, callback={}) + assert_that(json.loads(output.data.decode(output.charset)), is_('Some Error')) + assert_that(output.status_code, is_(500)) def test_execute_method_returns_list(self): self.router.invoke_method.return_value = ['a', 'b', 'c'] @@ -84,6 +104,7 @@ def test_execute_method_returns_list(self): self.router.invoke_method.assert_called_with(module=self.module2, method='remote_method', params=[], env={'variable1': 'value1'}, callback={}) assert_that(json.loads(output.data.decode(output.charset)), is_(['a', 'b', 'c'])) + assert_that(output.status_code, is_(200)) def test_invoking_unknown_module_returns_a_404(self): output = self.api_client.post(self.generate_module_path('new_module'), @@ -106,6 +127,7 @@ def test_listing_unknown_module_returns_a_404(self): assert_that(output.status_code, is_(404)) + class NoTrailingSlashApiTest(ApiTest): def generate_module_path(self, module_name): return '/{0}'.format(module_name) \ No newline at end of file diff --git a/ubersmith_remote_module_server/api.py b/ubersmith_remote_module_server/api.py index 4c42e55..f793704 100644 --- a/ubersmith_remote_module_server/api.py +++ b/ubersmith_remote_module_server/api.py @@ -41,8 +41,12 @@ def list_implemented_methods(self, module): def handle_remote_invocation(self, module): logging.debug("Handle remote invocation for {module}".format(module=module)) data = request.get_json() - output = self.router.invoke_method(module=module, **data) - return json_response(output, 200) + try: + output = self.router.invoke_method(module=module, **data) + return json_response(output, 200) + except Exception as e: + return json_response(str(e), 500) + def json_response(data, code): json_data = json.dumps(data, indent=None) From d72f73c568bb4537c4180eee740f45347a93453e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Tue, 14 Mar 2017 16:30:47 -0400 Subject: [PATCH 2/2] Add specific exception --- tests/test_api.py | 3 ++- ubersmith_remote_module_server/api.py | 4 +++- ubersmith_remote_module_server/exceptions.py | 4 ++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 22a5596..0e3dde9 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -19,6 +19,7 @@ import unittest from ubersmith_remote_module_server.api import Api +from ubersmith_remote_module_server.exceptions import RemoteModuleException class ApiTest(unittest.TestCase): @@ -69,7 +70,7 @@ def test_execute_method_returns_string(self): assert_that(output.status_code, is_(200)) def test_execute_method_raise_an_exception(self): - self.router.invoke_method.side_effect = Exception('Some Error') + self.router.invoke_method.side_effect = RemoteModuleException('Some Error') output = self.api_client.post(self.generate_module_path('module2'), headers={'Content-Type': 'application/json'}, data=json.dumps( diff --git a/ubersmith_remote_module_server/api.py b/ubersmith_remote_module_server/api.py index f793704..89baf88 100644 --- a/ubersmith_remote_module_server/api.py +++ b/ubersmith_remote_module_server/api.py @@ -17,6 +17,7 @@ import logging from flask import request, current_app +from ubersmith_remote_module_server.exceptions import RemoteModuleException class Api(object): @@ -44,7 +45,8 @@ def handle_remote_invocation(self, module): try: output = self.router.invoke_method(module=module, **data) return json_response(output, 200) - except Exception as e: + except RemoteModuleException as e: + logging.exception(e) return json_response(str(e), 500) diff --git a/ubersmith_remote_module_server/exceptions.py b/ubersmith_remote_module_server/exceptions.py index 27b5549..b65773d 100644 --- a/ubersmith_remote_module_server/exceptions.py +++ b/ubersmith_remote_module_server/exceptions.py @@ -23,3 +23,7 @@ class NamedArgumentsOnly(Exception): def __init__(self, msg="UbersmithCore was called with non-named arguments, " "you MUST use named arguments (kwargs)"): super(NamedArgumentsOnly, self).__init__(msg) + + +class RemoteModuleException(Exception): + pass