diff --git a/rq/job.py b/rq/job.py index da57e1d..83baacb 100644 --- a/rq/job.py +++ b/rq/job.py @@ -441,7 +441,6 @@ class Job(object): You can exclude serializing the `meta` dictionary by setting `include_meta=False`. - """ obj = {} obj['created_at'] = utcformat(self.created_at or utcnow()) @@ -458,7 +457,10 @@ class Job(object): if self.ended_at is not None: obj['ended_at'] = utcformat(self.ended_at) if self._result is not None: - obj['result'] = dumps(self._result) + try: + obj['result'] = dumps(self._result) + except: + obj['result'] = 'Unpickleable return value' if self.exc_info is not None: obj['exc_info'] = self.exc_info if self.timeout is not None: diff --git a/tests/test_job.py b/tests/test_job.py index 46d7d39..4f570af 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -5,6 +5,7 @@ from __future__ import (absolute_import, division, print_function, from datetime import datetime import time +from Queue import Queue from tests import fixtures, RQTestCase from tests.helpers import strip_microseconds @@ -292,6 +293,13 @@ class TestJob(RQTestCase): serialized2.pop('meta') self.assertDictEqual(serialized, serialized2) + def test_unpickleable_result(self): + """Unpickleable job result doesn't crash job.to_dict()""" + job = Job.create(func=fixtures.say_hello, args=('Lionel',)) + job._result = Queue() + data = job.to_dict() + self.assertEqual(data['result'], 'Unpickleable return value') + def test_result_ttl_is_persisted(self): """Ensure that job's result_ttl is set properly""" job = Job.create(func=fixtures.say_hello, args=('Lionel',), result_ttl=10)