errands
small jobs the runtime does for the studio.
git clone https://owenrusk.dev/errands.git
commit 510acc0b2dde401ac4b59e3c683a6eaa3b2b3f11 parent 8c1527bf3320bbfbd9927369ecd9bc0f7ddd1084 author Owen Rusk <owen@papermothgames.com> date 2026-02-10 14:50:41 -0600
jobs: one job failing doesn't stop the rest
| errands/jobs.py | +5 | -1 |
| tests/test_jobs.py | +10 | -0 |
diff --git a/errands/jobs.py b/errands/jobs.py index 35a4bba..0d6bfe8 100644 --- a/errands/jobs.py +++ b/errands/jobs.py @@ -42,7 +42,11 @@ def tick(now: datetime, last: dict[str, datetime], jobs: list[Job] | None = None if is_due(job, now, last.get(job.name)): last[job.name] = now log.info("%s", job.name)- job.run()+ try: + job.run() + except Exception: + log.exception("%s failed", job.name) + continue ran.append(job.name) return ran diff --git a/tests/test_jobs.py b/tests/test_jobs.py index 1458778..353449c 100644 --- a/tests/test_jobs.py +++ b/tests/test_jobs.py @@ -33,3 +33,13 @@ class TickTest(unittest.TestCase): self.assertEqual(jobs.tick(at(9), last, [job]), ["x"]) self.assertEqual(jobs.tick(at(9, 1), last, [job]), []) self.assertEqual(calls, [1]) + + def test_a_failure_doesnt_stop_the_rest(self): + def broken(): + raise RuntimeError("down") + + calls = [] + jobs_ = [jobs.Job("broken", broken, every=5), jobs.Job("fine", lambda: calls.append(1), every=5)] + with self.assertLogs("errands", level="ERROR"): + self.assertEqual(jobs.tick(at(9), {}, jobs_), ["fine"]) + self.assertEqual(calls, [1])