From: Michael Goldish <mgoldish@redhat.com>
To: autotest@test.kernel.org, kvm@vger.kernel.org
Cc: Michael Goldish <mgoldish@redhat.com>
Subject: [KVM-AUTOTEST PATCH 1/7] [RFC] Fix Unhandled* exceptions
Date: Mon, 3 Jan 2011 20:34:05 +0200 [thread overview]
Message-ID: <1294079651-21631-1-git-send-email-mgoldish@redhat.com> (raw)
In recent Python version, when exceptions are unpickled their __init__() method
is called again. The parameters passed to __init__() upon unpickling are
*self.args. Because the first execution of __init__() sets self.args to
something different from the parameters passed to __init__() (by passing
something to Exception.__init__()), upon unpickling __init__() is called with
unexpected parameters.
For example, if a NameError is raised in a test, UnhandledTestFail.__init__()
will call
Exception.__init__(self, "Unhandled NameError: ...").
Upon unpickling, UnhandledTestFail.__init__() will be called with "Unhandled
NameError: ..." which is a string. It will then call
Exception.__init__(self, "Unhandled str: Unhandled NameError: ...")
because str is not an instance of TestFail. The resulting exception's __str__()
method will return "Unhandled str: Unhandled NameError: ..." which isn't pretty.
To fix this, this patch makes the Unhandled* exceptions rely on __str__()
and attributes (self.unhandled_exception and self.traceback) instead of
__init__() and self.args. An alternative solution could be to check whether
the parameter passed to __init__() is a string, and if so, pass it to the parent
exception's __init__() without modification.
Signed-off-by: Michael Goldish <mgoldish@redhat.com>
---
client/bin/job.py | 6 ++--
client/common_lib/error.py | 51 ++++++++++++++++++++++++++++---------------
2 files changed, 36 insertions(+), 21 deletions(-)
diff --git a/client/bin/job.py b/client/bin/job.py
index 3d552ce..f4306fc 100644
--- a/client/bin/job.py
+++ b/client/bin/job.py
@@ -1182,13 +1182,13 @@ def runjob(control, drop_caches, options):
sys.exit(1)
except error.JobError, instance:
- logging.error("JOB ERROR: " + instance.args[0])
+ logging.error("JOB ERROR: " + str(instance))
if myjob:
command = None
if len(instance.args) > 1:
command = instance.args[1]
- myjob.record('ABORT', None, command, instance.args[0])
- myjob.record('END ABORT', None, None, instance.args[0])
+ myjob.record('ABORT', None, command, str(instance))
+ myjob.record('END ABORT', None, None, str(instance))
assert myjob._record_indent == 0
myjob.complete(1)
else:
diff --git a/client/common_lib/error.py b/client/common_lib/error.py
index 42dfe2b..71ba4e5 100644
--- a/client/common_lib/error.py
+++ b/client/common_lib/error.py
@@ -44,14 +44,19 @@ class JobError(AutotestError):
class UnhandledJobError(JobError):
"""Indicates an unhandled error in a job."""
def __init__(self, unhandled_exception):
- if isinstance(unhandled_exception, JobError):
- JobError.__init__(self, *unhandled_exception.args)
+ JobError.__init__(self, unhandled_exception)
+ self.unhandled_exception = unhandled_exception
+ self.traceback = traceback.format_exc()
+
+ def __str__(self):
+ if isinstance(self.unhandled_exception, JobError):
+ return JobError.__str__(self.unhandled_exception)
else:
msg = "Unhandled %s: %s"
- msg %= (unhandled_exception.__class__.__name__,
- unhandled_exception)
- msg += "\n" + traceback.format_exc()
- JobError.__init__(self, msg)
+ msg %= (self.unhandled_exception.__class__.__name__,
+ self.unhandled_exception)
+ msg += "\n" + self.traceback
+ return msg
class TestBaseException(AutotestError):
@@ -85,27 +90,37 @@ class TestWarn(TestBaseException):
class UnhandledTestError(TestError):
"""Indicates an unhandled error in a test."""
def __init__(self, unhandled_exception):
- if isinstance(unhandled_exception, TestError):
- TestError.__init__(self, *unhandled_exception.args)
+ TestError.__init__(self, unhandled_exception)
+ self.unhandled_exception = unhandled_exception
+ self.traceback = traceback.format_exc()
+
+ def __str__(self):
+ if isinstance(self.unhandled_exception, TestError):
+ return TestError.__str__(self.unhandled_exception)
else:
msg = "Unhandled %s: %s"
- msg %= (unhandled_exception.__class__.__name__,
- unhandled_exception)
- msg += "\n" + traceback.format_exc()
- TestError.__init__(self, msg)
+ msg %= (self.unhandled_exception.__class__.__name__,
+ self.unhandled_exception)
+ msg += "\n" + self.traceback
+ return msg
class UnhandledTestFail(TestFail):
"""Indicates an unhandled fail in a test."""
def __init__(self, unhandled_exception):
- if isinstance(unhandled_exception, TestFail):
- TestFail.__init__(self, *unhandled_exception.args)
+ TestFail.__init__(self, unhandled_exception)
+ self.unhandled_exception = unhandled_exception
+ self.traceback = traceback.format_exc()
+
+ def __str__(self):
+ if isinstance(self.unhandled_exception, TestFail):
+ return TestFail.__str__(self.unhandled_exception)
else:
msg = "Unhandled %s: %s"
- msg %= (unhandled_exception.__class__.__name__,
- unhandled_exception)
- msg += "\n" + traceback.format_exc()
- TestFail.__init__(self, msg)
+ msg %= (self.unhandled_exception.__class__.__name__,
+ self.unhandled_exception)
+ msg += "\n" + self.traceback
+ return msg
class CmdError(TestError):
--
1.7.3.4
next reply other threads:[~2011-01-03 18:33 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-03 18:34 Michael Goldish [this message]
2011-01-03 18:34 ` [KVM-AUTOTEST PATCH 2/7] [RFC] CmdError: remove extra blank line between methods Michael Goldish
2011-01-03 18:34 ` [KVM-AUTOTEST PATCH 3/7] [RFC] Introduce exception context strings Michael Goldish
2011-01-03 19:26 ` Eduardo Habkost
2011-01-03 19:42 ` [Autotest] " Eduardo Habkost
2011-01-03 19:48 ` Michael Goldish
2011-01-03 20:16 ` Eduardo Habkost
2011-01-03 21:07 ` Michael Goldish
2011-01-03 21:22 ` Eduardo Habkost
2011-01-03 22:06 ` [Autotest] " Eduardo Habkost
2011-01-03 22:56 ` Michael Goldish
2011-01-04 15:08 ` Eduardo Habkost
2011-01-04 15:20 ` Eduardo Habkost
2011-01-03 20:26 ` Eduardo Habkost
2011-01-03 20:41 ` [Autotest] " Michael Goldish
2011-01-03 18:34 ` [KVM-AUTOTEST PATCH 4/7] [RFC] Embed context information in exception strings Michael Goldish
2011-01-03 18:34 ` [KVM-AUTOTEST PATCH 5/7] [RFC] Set the .context attribute for exceptions in _call_test_function() Michael Goldish
2011-01-03 18:34 ` [KVM-AUTOTEST PATCH 6/7] [RFC] KVM test: use error.context() in migration_with_file_transfer Michael Goldish
2011-01-03 18:34 ` [KVM-AUTOTEST PATCH 7/7] [RFC] KVM test: use error.context() in kvm_preprocessing.py Michael Goldish
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1294079651-21631-1-git-send-email-mgoldish@redhat.com \
--to=mgoldish@redhat.com \
--cc=autotest@test.kernel.org \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox