Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

log traceback when exception is added to message

  • Loading branch information...
commit 0cc9715c070e5db6967e189060b206246a9b84d9 1 parent d01f018
Jussi Malinen authored
View
4 src/robotide/log/log.py
@@ -13,7 +13,7 @@
# limitations under the License.
import wx
-from robotide.pluginapi import Plugin, ActionInfo, RideLogMessage
+from robotide.pluginapi import Plugin, ActionInfo, RideLog
from robotide.context.font import Font
@@ -27,7 +27,7 @@ def __init__(self, app):
def enable(self):
self._create_menu()
- self.subscribe(self._log_message, RideLogMessage)
+ self.subscribe(self._log_message, RideLog)
def disable(self):
self.unsubscribe_all()
View
6 src/robotide/namespace/cache.py
@@ -18,7 +18,7 @@
from robotide.context import SETTINGS
from robotide.spec import LibrarySpec
from robotide.robotapi import normpath
-from robotide.publish.messages import RideLogMessage
+from robotide.publish.messages import RideLogException
class LibraryCache(object):
@@ -34,8 +34,8 @@ def add_library(self, name, args=None):
try:
kws = LibrarySpec(name, args).keywords
except Exception, err:
- RideLogMessage(message='Importing library %s failed with exception %s.' % (name, err),
- level='WARN').publish()
+ RideLogException(message='Importing library %s failed with exception %s.' % (name, err),
+ exception=err, level='WARN').publish()
finally:
self.library_keywords[self._key(name, args)] = kws
View
44 src/robotide/publish/messages.py
@@ -18,6 +18,8 @@
from robotide import utils
import messagetype
+import sys
+import traceback
class RideMessage(object):
@@ -63,17 +65,26 @@ def publish(self):
try:
self._publish(self)
except Exception, err:
- self._publish('Error in publishing message: ' + RideLogMessage(message=str(err), level='ERROR'))
+ self._publish(RideLogException(message='Error in publishing message: ' + str(err),
+ exception=err, level='ERROR'))
def _publish(self, msg):
WxPublisher().sendMessage(msg.topic, msg)
+class RideLog(RideMessage):
+ """This class represents a general purpose log message.
+
+ Subclasses of this be may used to inform error conditions or to provide
+ some kind of debugging information.
+ """
+ data = ['message', 'level', 'timestamp']
-class RideLogMessage(RideMessage):
+
+class RideLogMessage(RideLog):
"""This class represents a general purpose log message.
This message may used to inform error conditions or to provide
- some kind of debugging information, mainly to be shown to users.
+ some kind of debugging information.
"""
data = ['message', 'level', 'timestamp']
@@ -87,6 +98,33 @@ def __init__(self, message, level='INFO'):
timestamp=utils.get_timestamp())
+class RideLogException(RideLog):
+ """This class represents a general purpose log message with a traceback
+ appended to message text. Also the original exception is included with
+ the message.
+
+ This message may used to inform error conditions or to provide
+ some kind of debugging information.
+ """
+ data = ['message', 'level', 'timestamp', 'exception']
+
+ def __init__(self, message, exception, level='INFO'):
+ """Initializes a RIDE log exception.
+
+ The log ``level`` has default value ``INFO`` and the ``timestamp``
+ is generated automatically. Message is automatically appended with
+ a traceback.
+ """
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ if exc_traceback:
+ tb = traceback.extract_tb(exc_traceback)
+ message += '\n\nTraceback (most recent call last):\n' + ''.join(traceback.format_list(tb))
+ RideMessage.__init__(self, message=message, level=level,
+ timestamp=utils.get_timestamp(),
+ exception=exception)
+
+
+
class RideTreeSelection(RideMessage):
"""Sent whenever user selects a node from the tree."""
data = ['node', 'item', 'text']
View
9 src/robotide/publish/publisher.py
@@ -14,7 +14,9 @@
from wx.lib.pubsub import Publisher as WxPublisher
-from messages import RideLogMessage
+from messages import RideLogException
+import traceback
+import sys
class Publisher(object):
@@ -84,5 +86,6 @@ def __call__(self, event):
self.listener(event.data)
except Exception, err:
# Prevent infinite recusrion if RideLogMessage listerner is broken,
- if not isinstance(event.data, RideLogMessage):
- RideLogMessage(message='Error in listener: ' + unicode(err), level='ERROR').publish()
+ if not isinstance(event.data, RideLogException):
+ RideLogException(message='Error in listener: ' + unicode(err),
+ exception=err, level='ERROR').publish()
View
4 src/robotide/spec/xmlreaders.py
@@ -16,7 +16,7 @@
from robotide.robotapi import TestLibrary as RobotTestLibrary
from robotide.errors import DataError
-from robotide.publish import RideLogMessage
+from robotide.publish import RideLogException
from robotide import utils
from iteminfo import LibraryKeywordInfo, _XMLKeywordContent
@@ -58,7 +58,7 @@ def __init__(self, name, args=None):
self.keywords, self.doc = self._init_from_specfile(specfile)
if not self.keywords:
msg = 'Importing test library "%s" failed: %s' % (self.name, err)
- RideLogMessage(message=msg, level='WARN').publish()
+ RideLogException(message=msg, exception=err, level='WARN').publish()
def _init_from_library(self, name, args):
lib = RobotTestLibrary(name, args)
View
4 src/robotide/ui/pluginmanager.py
@@ -16,7 +16,7 @@
from wx.lib.scrolledpanel import ScrolledPanel
from robotide.context import LOG
-from robotide.publish import RideLogMessage
+from robotide.publish import RideLogException
class PluginManager(object):
@@ -107,7 +107,7 @@ def _execute(self, method):
self._plugin.error = err
self._plugin.doc = msg
LOG.error(msg)
- RideLogMessage(message=msg, level='ERROR').publish()
+ RideLogException(message=msg, exception=err, level='ERROR').publish()
class _PluginRow(wx.Panel):
View
12 utest/plugin/test_messages.py
@@ -15,9 +15,9 @@
import unittest
from robot.utils.asserts import assert_equals, assert_none, assert_false, \
- assert_raises_with_msg
+ assert_raises_with_msg, assert_true
-from robotide.publish import RideMessage, RideLogMessage, PUBLISHER
+from robotide.publish import RideMessage, RideLog, PUBLISHER
from robotide.pluginapi import Plugin
@@ -155,14 +155,14 @@ def tearDown(self):
self.plugin.disable()
def test_broken_listener(self):
- self.plugin.subscribe(self.plugin.error_listener, RideLogMessage)
+ self.plugin.subscribe(self.plugin.error_listener, RideLog)
RideTestMessage().publish()
- assert_equals(self.plugin.error.message, 'Error in listener: ride.test')
- assert_equals(self.plugin.error.topic, 'ride.log')
+ assert_true(self.plugin.error.message.startswith('Error in listener: ride.test\n\nTraceback (most recent call last):'))
+ assert_equals(self.plugin.error.topic, 'ride.log.exception')
assert_equals(self.plugin.error.level, 'ERROR')
def test_broken_error_listener_does_not_cause_infinite_recusrion(self):
- self.plugin.subscribe(self.plugin.broken_listener, RideLogMessage)
+ self.plugin.subscribe(self.plugin.broken_listener, RideLog)
class BrokenListenerPlugin(Plugin):
View
11 utest/publish/test_message_publishing.py
@@ -17,7 +17,7 @@
from robot.utils.asserts import assert_equals, assert_raises_with_msg,\
assert_true
-from robotide.publish import RideMessage, RideLogMessage, Publisher
+from robotide.publish import RideMessage, RideLogMessage, RideLogException, Publisher
_ARGS_ERROR = "Argument mismatch, expected: ['foo', 'bar']"
@@ -66,6 +66,15 @@ def test_log_message(self):
assert_equals(msg.level, 'ERROR')
assert_true(msg.timestamp.startswith('20'))
+ def test_log_exception(self):
+ try:
+ 1/0
+ except Exception, err:
+ msg = RideLogException(message='Some error text', exception=err, level='ERROR')
+ assert_true(msg.message.startswith('Some error text\n\nTraceback (most recent call last):'))
+ assert_equals(msg.level, 'ERROR')
+ assert_true(msg.timestamp.startswith('20'))
+
class TestPublisher(unittest.TestCase):
Please sign in to comment.
Something went wrong with that request. Please try again.