Commit 051a23cb authored by Jerome Mariette's avatar Jerome Mariette
Browse files

implement a different way to handle errors

parent 541c2ced
......@@ -25,7 +25,6 @@ from functools import wraps
import time
import os
import argparse
import logging
from argparse import ArgumentTypeError
......
......@@ -26,12 +26,13 @@ import pickle
import time
import threading
import types
import logging
import datetime
import logging
import traceback
from logging import FileHandler
from ConfigParser import ConfigParser, NoOptionError
from inspect import getcallargs
from datetime import date as ddate
import jflow
import jflow.utils as utils
......@@ -116,7 +117,6 @@ class Workflow(threading.Thread):
self.end_time = None
self.step = None
self.stderr = None
self.stderrfh = None
self.args = args
self.dynamic_component_present = False
self.__to_address = None
......@@ -269,8 +269,7 @@ class Workflow(threading.Thread):
paramsexclude.group = new_group
# it might be a mutliple param rule
else:
logging.getLogger("wf." + str(self.__class__.__name__)).exception("Exclusion rule cannot be applied within a MultiParameter or a MultiParameterList")
raise
self._log("Exclusion rule cannot be applied within a MultiParameter or a MultiParameterList", raisee=True)
# save this for MultiParameter internal exclusion rules, works on command line, not supported on gui
# for attribute_value in self.__dict__.values():
# if issubclass(attribute_value.__class__, MultiParameter) or issubclass(attribute_value.__class__, MultiParameterList):
......@@ -430,8 +429,6 @@ class Workflow(threading.Thread):
def delete(self):
if self.get_status() in [self.STATUS_COMPLETED, self.STATUS_FAILED, self.STATUS_ABORTED]:
# first close the open files
self.stderrfh.close()
utils.robust_rmtree(self.directory)
@staticmethod
......@@ -528,6 +525,7 @@ class Workflow(threading.Thread):
return pretty_str
def get_errors(self):
if os.path.isfile(self.stderr):
error = {
"title" : "",
"msg" : list(),
......@@ -569,6 +567,8 @@ class Workflow(threading.Thread):
return { "msg" : error["msg"], "location" : last_stack_location }
else:
return None
else:
return None
def get_outputs_per_components(self):
outputs_files = {}
......@@ -581,8 +581,6 @@ class Workflow(threading.Thread):
def __setstate__(self, state):
self.__dict__ = state.copy()
self.external_components = self._import_external_components()
self.stderrfh = None
self.stderr = self._set_stderr(True)
threading.Thread.__init__(self, name=self.name)
def __getstate__(self):
......@@ -595,9 +593,6 @@ class Workflow(threading.Thread):
del odict['_Thread__stderr']
if odict.has_key('external_components') :
del odict['external_components']
if odict.has_key('stderrfh') :
self.stderrfh.close()
del odict['stderrfh']
return odict
def set_to_address(self, to_address):
......@@ -644,20 +639,20 @@ class Workflow(threading.Thread):
s.starttls()
s.login(me, fromp)
except smtplib.SMTPHeloError:
logging.getLogger("wf." + str(self.id)).debug("The server didn't reply properly to the HELO greeting.")
self._log("The server didn't reply properly to the HELO greeting.", level="debug", traceback=traceback.format_exc())
except smtplib.SMTPAuthenticationError:
logging.getLogger("wf." + str(self.id)).debug("The server didn't accept the username/password combination.")
self._log("The server didn't accept the username/password combination.", level="debug", traceback=traceback.format_exc())
except smtplib.SMTPException:
logging.getLogger("wf." + str(self.id)).debug("No suitable authentication method was found, or the server does not support the STARTTLS extension.")
self._log("No suitable authentication method was found, or the server does not support the STARTTLS extension.", level="debug", traceback=traceback.format_exc())
except RuntimeError:
logging.getLogger("wf." + str(self.id)).debug("SSL/TLS support is not available to your Python interpreter.")
self._log("SSL/TLS support is not available to your Python interpreter.", level="debug", traceback=traceback.format_exc())
except:
logging.getLogger("wf." + str(self.id)).debug("Unhandled error when sending mail.")
self._log("Unhandled error when sending mail.", level="debug", traceback=traceback.format_exc())
finally:
s.sendmail(me, [you], msg.as_string())
s.close()
except:
logging.getLogger("wf." + str(self.id)).debug("Impossible to connect to smtp server '" + smtps + "'")
self._log("Impossible to connect to smtp server '" + smtps + "'", level="debug", traceback=traceback.format_exc())
def get_parameters_per_groups(self):
name = self.get_name()
......@@ -862,7 +857,7 @@ class Workflow(threading.Thread):
self._serialize()
self._send_email()
except Exception as e:
logging.getLogger("wf." + str(self.id)).exception(str(e))
self._log(str(e), traceback=traceback.format_exc())
utils.display_error_message(str(e))
def _update_status_from_log(self):
......@@ -961,23 +956,28 @@ class Workflow(threading.Thread):
sys.stdout.write('{0:>10} {1:>10} {2}\n'.format('', 'COMMAND', node.command))
def _set_stderr(self, keep_same_error_file=False):
# if it is specified to keep the same error file, keep with it
if not keep_same_error_file:
def _set_stderr(self):
if hasattr(self, "stderr") and self.stderr is not None:
os.rename( self.stderr, os.path.join(self.directory, str(time.time()) + self.STDERR_FILE_NAME + self.OLD_EXTENSION) )
stderr = os.path.join(self.directory, self.STDERR_FILE_NAME)
logger = logging.getLogger( "wf." + str(self.id) )
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter( '## %(asctime)s :: %(message)s' )
if self.stderrfh is None:
self.stderrfh = FileHandler(stderr, 'a')
self.stderrfh.setLevel(logging.ERROR)
self.stderrfh.setFormatter(formatter)
logger.addHandler(self.stderrfh)
return stderr
def _log(self, msg, level="exception", raisee=False, traceback=None):
if level == "exception":
logging.getLogger("wf." + str(self.id)).exception(msg)
elif level == "debug":
logging.getLogger("wf." + str(self.id)).debug(msg)
logh = open(self.stderr, "a")
today = ddate.today()
logh.write("## " + today.strftime("%c") + " :: " + msg + "\n")
if traceback: logh.write(traceback)
logh.close()
if raisee:
raise Exception(msg)
def _execute_weaver(self, engine_wrapper=None):
# Add nest path and path to script to Python module path to allow
# for importing modules outside of $PYTHONPATH
......@@ -1060,7 +1060,7 @@ class Workflow(threading.Thread):
if issubclass(obj, jflow.component.Component) and obj.__name__ != jflow.component.Component.__name__:
pckge[class_name] = modname
except Exception as e:
logging.getLogger("wf." + str(self.id)).debug("Component <{0}> cannot be loaded: {1}".format(modname, e))
self._log("Component <{0}> cannot be loaded: {1}".format(modname, e), level="debug", traceback=traceback.format_exc())
# finally import workflows shared packages
workflows_dir = os.path.dirname(os.path.dirname(inspect.getfile(self.__class__)))
for importer, modname, ispkg in pkgutil.iter_modules([os.path.join(workflows_dir, "components")], "workflows.components."):
......@@ -1070,7 +1070,7 @@ class Workflow(threading.Thread):
if issubclass(obj, jflow.component.Component) and obj.__name__ != jflow.component.Component.__name__:
pckge[class_name] = modname
except Exception as e:
logging.getLogger("wf." + str(self.id)).debug("Component <{0}> cannot be loaded: {1}".format(modname, e))
self._log("Component <{0}> cannot be loaded: {1}".format(modname, e), level="debug", traceback=traceback.format_exc())
return pckge
def _import_external_components(self):
......@@ -1085,7 +1085,7 @@ class Workflow(threading.Thread):
if issubclass(obj, jflow.extparser.ExternalParser) and obj.__name__ != jflow.extparser.ExternalParser.__name__:
parsers.append(obj())
except Exception as e:
logging.getLogger("wf." + str(self.id)).debug("Parser <{0}> cannot be loaded: {1}".format(modname, e))
self._log("Parser <{0}> cannot be loaded: {1}".format(modname, e), level="debug", traceback=traceback.format_exc())
for parser in parsers :
# import from pipeline components package ...
......
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