Commit 4e744350 authored by Julien Muchembled's avatar Julien Muchembled

CMFActivity: revamp notification mail

parent 2e2b366c
......@@ -160,6 +160,11 @@ class Message(BaseMessage):
active_process = None
active_process_uid = None
call_traceback = None
is_executed = MESSAGE_NOT_EXECUTED
processing = None
traceback = None
exc_type = None
def __init__(self, obj, active_process, activity_kw, method_id, args, kw):
if isinstance(obj, str):
......@@ -178,18 +183,11 @@ class Message(BaseMessage):
self.method_id = method_id
self.args = args
self.kw = kw
self.is_executed = MESSAGE_NOT_EXECUTED
self.exc_type = None
self.exc_value = None
self.traceback = None
if activity_creation_trace and format_list is not None:
# Save current traceback, to make it possible to tell where a message
# was generated.
# Strip last stack entry, since it will always be the same.
self.call_traceback = ''.join(format_list(extract_stack()[:-1]))
else:
self.call_traceback = None
self.processing = None
self.user_name = str(_getAuthenticatedUser(self))
# Store REQUEST Info
self.request_info = {}
......@@ -263,11 +261,12 @@ class Message(BaseMessage):
try:
obj = self.getObject(activity_tool)
except KeyError:
exc_info = sys.exc_info()
LOG('CMFActivity', ERROR,
'Message failed in getting an object from the path %r' % \
(self.object_path,),
error=sys.exc_info())
self.setExecutionState(MESSAGE_NOT_EXECUTABLE, context=activity_tool)
'Message failed in getting an object from the path %r'
% (self.object_path,), error=exc_info)
self.setExecutionState(MESSAGE_NOT_EXECUTABLE, exc_info,
context=activity_tool)
else:
try:
old_security_manager = getSecurityManager()
......@@ -279,13 +278,14 @@ class Message(BaseMessage):
# XXX: There is no check to see if user is allowed to access
# that method !
method = getattr(obj, self.method_id)
except:
except Exception:
exc_info = sys.exc_info()
LOG('CMFActivity', ERROR,
'Message failed in getting a method %r from an object %r' % \
(self.method_id, obj,),
error=sys.exc_info())
'Message failed in getting a method %r from an object %r'
% (self.method_id, obj), error=exc_info)
method = None
self.setExecutionState(MESSAGE_NOT_EXECUTABLE, context=activity_tool)
self.setExecutionState(MESSAGE_NOT_EXECUTABLE, exc_info,
context=activity_tool)
else:
if activity_tool.activity_timing_log:
result = activity_timing_method(method, self.args, self.kw)
......@@ -316,13 +316,8 @@ class Message(BaseMessage):
portal = activity_tool.getPortalObject()
user_email = portal.getProperty('email_to_address',
portal.getProperty('email_from_address'))
email_from_name = portal.getProperty('email_from_name',
portal.getProperty('email_from_address'))
call_traceback = ''
if self.call_traceback:
call_traceback = 'Created at:\n%s' % self.call_traceback
fail_count = self.line.retry + 1
if self.getExecutionState() == MESSAGE_NOT_EXECUTABLE:
message = "Not executable activity"
......@@ -342,21 +337,18 @@ Document: %s
Method: %s
Arguments: %r
Named Parameters: %r
%s
Exception: %s %s
%s
""" % (email_from_name, activity_tool.email_from_address, user_email,
message, path, self.method_id,
activity_tool.getCurrentNode(), fail_count,
self.user_name, path, self.method_id, self.args, self.kw,
call_traceback, self.exc_type, self.exc_value, self.traceback)
""" % (email_from_name, activity_tool.email_from_address, user_email, message,
path, self.method_id, activity_tool.getCurrentNode(), fail_count,
self.user_name, path, self.method_id, self.args, self.kw)
if self.traceback:
mail_text += '\nException:\n' + self.traceback
if self.call_traceback:
mail_text += '\nCreated at:\n' + self.call_traceback
try:
activity_tool.MailHost.send( mail_text )
portal.MailHost.send(mail_text)
except (socket.error, MailHostError), message:
LOG('ActivityTool.notifyUser', WARNING, 'Mail containing failure information failed to be sent: %s. Exception was: %s %s\n%s' % (message, self.exc_type, self.exc_value, self.traceback))
LOG('ActivityTool.notifyUser', WARNING,
'Mail containing failure information failed to be sent: %s' % message)
def reactivate(self, activity_tool, activity=DEFAULT_ACTIVITY):
# Reactivate the original object.
......@@ -400,24 +392,22 @@ Exception: %s %s
assert is_executed in (MESSAGE_NOT_EXECUTED, MESSAGE_EXECUTED, MESSAGE_NOT_EXECUTABLE)
self.is_executed = is_executed
if is_executed != MESSAGE_EXECUTED:
if exc_info is None:
if not exc_info:
exc_info = sys.exc_info()
if exc_info == (None, None, None):
self.exc_type = exc_info[0]
if exc_info[0] is None:
# Raise a dummy exception, ignore it, fetch it and use it as if it was the error causing message non-execution. This will help identifyting the cause of this misbehaviour.
try:
raise Exception, 'Message execution failed, but there is no exception to explain it. This is a dummy exception so that one can track down why we end up here outside of an exception handling code path.'
except:
pass
exc_info = sys.exc_info()
except Exception:
exc_info = sys.exc_info()
if log:
LOG('ActivityTool', WARNING, 'Could not call method %s on object %s. Activity created at:\n%s' % (self.method_id, self.object_path, self.call_traceback), error=exc_info)
# push the error in ZODB error_log
error_log = getattr(context, 'error_log', None)
if error_log is not None:
error_log.raising(exc_info)
self.exc_type = exc_info[0]
self.exc_value = str(exc_info[1])
self.traceback = ''.join(ExceptionFormatter.format_exception(*exc_info))
self.traceback = ''.join(ExceptionFormatter.format_exception(*exc_info)[1:])
def getExecutionState(self):
return self.is_executed
......@@ -432,8 +422,9 @@ class Method:
self.__method_id = method_id
def __call__(self, *args, **kw):
m = Message(self.__passive_self, self.__active_process, self.__kw, self.__method_id, args, kw)
portal_activities = self.__passive_self.getPortalObject().portal_activities
passive_self = self.__passive_self
m = Message(passive_self, self.__active_process, self.__kw, self.__method_id, args, kw)
portal_activities = passive_self.getPortalObject().portal_activities
if portal_activities.activity_tracking:
activity_tracking_logger.info('queuing message: activity=%s, object_path=%s, method_id=%s, args=%s, kw=%s, activity_kw=%s, user_name=%s' % (self.__activity, '/'.join(m.object_path), m.method_id, m.args, m.kw, m.activity_kw, m.user_name))
activity_dict[self.__activity].queueMessage(portal_activities, m)
......@@ -1200,11 +1191,11 @@ class ActivityTool (Folder, UniqueObject):
try:
obj = m.getObject(self)
except KeyError:
exc_info = sys.exc_info()
LOG('CMFActivity', ERROR,
'Message failed in getting an object from the path %r' % \
(m.object_path,),
error=sys.exc_info())
m.setExecutionState(MESSAGE_NOT_EXECUTABLE, context=self)
'Message failed in getting an object from the path %r'
% (m.object_path,), error=exc_info)
m.setExecutionState(MESSAGE_NOT_EXECUTABLE, exc_info, context=self)
continue
try:
if m.hasExpandMethod():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment