Search code examples
pythontry-exceptapscheduler

Python APScheduler - Catching raised exceptions in callback method


I am using the Python APScheduler and I wish to catch the raised exceptions from the callback method, however unsure as to how to do this. I have provided my code so far however I am stuck on how to do this appropriately. Any help would be appreciated.

import time
from apscheduler.schedulers.background import BackgroundScheduler


def expiry_callback():
    raise ValueError
    print("inside job")


sched = BackgroundScheduler(daemon=True)
sched.add_job(expiry_callback,'interval',seconds=1)

try:
    sched.start()
except ValueError as e:
    print(f'ran into an issue!! {e}')

try:
    while True:
        time.sleep(5)
except (KeyboardInterrupt, SystemExit):
    sched.shutdown()

stacktrace:

/Users/me/Documents/environments/my_env/bin/python3.9 /Users/me/PycharmProjects/pythonProject2/run.py
Job "expiry_callback (trigger: interval[0:00:01], next run at: 2021-08-24 22:33:26 MDT)" raised an exception
Traceback (most recent call last):
  File "/Users/me/Documents/environments/my_env/lib/python3.9/site-packages/apscheduler/executors/base.py", line 125, in run_job
    retval = job.func(*job.args, **job.kwargs)
  File "/Users/me/PycharmProjects/pythonProject2/run.py", line 6, in expiry_callback
    raise ValueError
ValueError

Process finished with exit code 0

Solution

  • Calling sched.start() only starts the background thread that executes the callback function but does not call the callback function itself so it is never going to produce the exception.

    If you're looking to handle exceptions from callback functions in a consistent way, you can instead call the via a wrapper function that catches a given exception and outputs the error in a definite manner:

    # insert definition of expiry_callback before this line
    
    def catch_exception(func, exception):
        def wrapper():
            try:
                func()
            except exception as e:
                print(f'ran into an issue!! {e}')
        return wrapper
    
    sched = BackgroundScheduler(daemon=True)
    sched.add_job(catch_exception(expiry_callback, ValueError),'interval',seconds=1)
    
    sched.start()
    
    # insert idle code after this line
    

    Demo: https://replit.com/@blhsing/BlueCreepyMethod