Author: laukpe
Date: Wed Sep 24 09:28:34 2008
New Revision: 819

Modified:
   trunk/proto/remote/python/robotremoteserver.py

Log:
Include traceback in returned output

Modified: trunk/proto/remote/python/robotremoteserver.py
==============================================================================
--- trunk/proto/remote/python/robotremoteserver.py      (original)
+++ trunk/proto/remote/python/robotremoteserver.py      Wed Sep 24 09:28:34 2008
@@ -1,5 +1,6 @@
 import sys
 import inspect
+import traceback
 from StringIO import StringIO
 from SimpleXMLRPCServer import SimpleXMLRPCServer
 try:
@@ -40,16 +41,20 @@
         return names + ['stop_remote_server']

     def run_keyword(self, name, args):
-        result = {'status':'PASS', 'return':'', 'message':'',  'output':''}
+        result = {'status':'PASS', 'return':'', 'message':'', 'output':''}
         self._intercept_stdout()
         try:
             return_value = self._get_keyword(name)(*args)
         except:
             result['status'] = 'FAIL'
-            result['message'] = self._get_error_message()
+            result['message'], trace = self._get_error_details()
         else:
             result['return'] = self._handle_return_value(return_value)
-        result['output'] = self._restore_stdout()
+            trace = None
+        output = self._restore_stdout()
+        if trace is not None:
+ output = output != '' and '%s\n*INFO* %s' % (output, trace) or trace
+        result['output'] = output
         return result

     def get_keyword_arguments(self, name):
@@ -74,17 +79,29 @@
             return self.stop_remote_server
         return getattr(self._library, name)

-    def _get_error_message(self):
-        # TODO: Return details too
-        exc_type, exc_value, exc_tp = sys.exc_info()
+    def _get_error_details(self):
+        exc_type, exc_value, exc_tb = sys.exc_info()
+        if exc_type in (SystemExit, KeyboardInterrupt):
+            self._restore_stdout()
+            raise
+        return (self._get_error_message(exc_type, exc_value),
+                self._get_error_traceback(exc_tb))
+
+    def _get_error_message(self, exc_type, exc_value):
         name = exc_type.__name__
         message = str(exc_value)
         if not message:
             return name
-        if name in ['AssertionError', 'RuntimeError', 'Exception']:
+        if name in ('AssertionError', 'RuntimeError', 'Exception'):
             return message
         return '%s: %s' % (name, message)
-
+
+    def _get_error_traceback(self, exc_tb):
+        # Latest entry originates from this class so it can be removed
+        entries = traceback.extract_tb(exc_tb)[1:]
+        trace = ''.join(traceback.format_list(entries))
+        return 'Traceback (most recent call last):\n' + trace
+
     def _handle_return_value(self, ret):
         if isinstance(ret, (basestring, int, long, float, bool)):
             return ret

Reply via email to