@@ -107,11 +107,43 @@ async def my_recovery_handler(exc: Exception, context: JobContext) -> str:
107107@app.task (exception_handlers = {ValueError : my_recovery_handler})
108108async def my_task () -> None :
109109 raise ValueError (" Oops!" )
110+ ```
111+
112+ ### 3. Aborting Retries with NoResultError
113+
114+ Sometimes, an error can be fatal and retrying a task (even if the ` retry ` configuration is set) would be a waste of resources.
115+ In these cases, it is recommended to raise the ` jobify.exceptions.NoResultError ` exception.
116+
117+ - When this exception is raised, the job's status will be set to FAILED.
118+ - The ` RetryMiddleware ` component will catch this exception and stop all further retries.
119+ - No more retries will be attempted.
120+
121+ ``` python
122+ import asyncio
123+
124+ from jobify import JobContext, Jobify
125+ from jobify.exceptions import NoResultError
126+
127+ app = Jobify()
128+
129+ async def fatal_error_handler (exc : Exception , context : JobContext) -> None :
130+ print (f " Fatal error in job { context.job.id} : { exc} " )
131+ # Signal that we should stop retries and fail the job immediately
132+ raise NoResultError
133+
134+ @app.task (retry = 3 , exception_handlers = {ValueError : fatal_error_handler})
135+ async def my_task () -> None :
136+ raise ValueError (" Corrupted data!" )
137+
138+ async def main () -> None :
139+ async with app:
140+ job = await my_task.push()
141+ await job.wait()
142+
143+ print (job.status) # FAILED
144+ print (job.exception) # NoResultError
110145
111- # ... after execution ...
112- await job.wait()
113- print (job.status) # SUCCESS
114- print (job.result()) # "default_value"
146+ asyncio.run(main())
115147```
116148
117149## Example: Hierarchical Handling
0 commit comments