From 07fef85dd2c648c5b731625e269a18677755c4a9 Mon Sep 17 00:00:00 2001 From: gabriels1234 <96071233+gabriels1234@users.noreply.github.com> Date: Wed, 3 May 2023 03:27:31 -0400 Subject: [PATCH] Catch serializer TypeError Exception (#1872) * Catch serializer TypeError Exception * Add test for unserializable job.meta --- rq/job.py | 5 ++++- tests/test_worker.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/rq/job.py b/rq/job.py index 61bc9aa3..5094b2da 100644 --- a/rq/job.py +++ b/rq/job.py @@ -912,7 +912,10 @@ class Job: self.allow_dependency_failures = bool(int(allow_failures)) if allow_failures else None self.enqueue_at_front = bool(int(obj['enqueue_at_front'])) if 'enqueue_at_front' in obj else None self.ttl = int(obj.get('ttl')) if obj.get('ttl') else None - self.meta = self.serializer.loads(obj.get('meta')) if obj.get('meta') else {} + try: + self.meta = self.serializer.loads(obj.get('meta')) if obj.get('meta') else {} + except Exception: # depends on the serializer + self.meta = {'unserialized': obj.get('meta', {})} self.retries_left = int(obj.get('retries_left')) if obj.get('retries_left') else None if obj.get('retry_intervals'): diff --git a/tests/test_worker.py b/tests/test_worker.py index d9b61216..5410180f 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -225,6 +225,23 @@ class TestWorker(RQTestCase): failed_job_registry = FailedJobRegistry(queue=q) self.assertTrue(job in failed_job_registry) + def test_meta_is_unserializable(self): + """Unserializable jobs are put on the failed job registry.""" + q = Queue() + self.assertEqual(q.count, 0) + + # NOTE: We have to fake this enqueueing for this test case. + # What we're simulating here is a call to a function that is not + # importable from the worker process. + job = Job.create(func=do_nothing, origin=q.name, meta={'key': 'value'}) + job.save() + + invalid_meta = '{{{{{{{{INVALID_JSON' + self.testconn.hset(job.key, 'meta', invalid_meta) + job.refresh() + self.assertIsInstance(job.meta, dict) + self.assertTrue('unserialized' in job.meta.keys()) + @mock.patch('rq.worker.logger.error') def test_deserializing_failure_is_handled(self, mock_logger_error): """