diff --git a/docs/background.md b/docs/background.md index e10832a92..a6bfd8c5f 100644 --- a/docs/background.md +++ b/docs/background.md @@ -72,3 +72,7 @@ routes = [ app = Starlette(routes=routes) ``` + +!!! important + The tasks are executed in order. In case one of the tasks raises + an exception, the following tasks will not get the opportunity to be executed. diff --git a/tests/test_background.py b/tests/test_background.py index e299ec362..fbe9dbf1b 100644 --- a/tests/test_background.py +++ b/tests/test_background.py @@ -1,5 +1,10 @@ +from typing import Callable + +import pytest + from starlette.background import BackgroundTask, BackgroundTasks from starlette.responses import Response +from starlette.testclient import TestClient def test_async_task(test_client_factory): @@ -40,7 +45,7 @@ async def app(scope, receive, send): assert TASK_COMPLETE -def test_multiple_tasks(test_client_factory): +def test_multiple_tasks(test_client_factory: Callable[..., TestClient]): TASK_COUNTER = 0 def increment(amount): @@ -61,3 +66,29 @@ async def app(scope, receive, send): response = client.get("/") assert response.text == "tasks initiated" assert TASK_COUNTER == 1 + 2 + 3 + + +def test_multi_tasks_failure_avoids_next_execution( + test_client_factory: Callable[..., TestClient] +) -> None: + TASK_COUNTER = 0 + + def increment(): + nonlocal TASK_COUNTER + TASK_COUNTER += 1 + if TASK_COUNTER == 1: + raise Exception("task failed") + + async def app(scope, receive, send): + tasks = BackgroundTasks() + tasks.add_task(increment) + tasks.add_task(increment) + response = Response( + "tasks initiated", media_type="text/plain", background=tasks + ) + await response(scope, receive, send) + + client = test_client_factory(app) + with pytest.raises(Exception): + client.get("/") + assert TASK_COUNTER == 1