I found a way to do what I wanted.
I created a job filter that implements IApplyStateFilter
public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
var deletedState = context.NewState as DeletedState;
if (deletedState != null)
// Execute code when the job has failed on all its attempts
Hi, thanks for this idea… now I can send email to myself whenever a job exhausted all its retries…
But I am curious, why did you choose OnAttemptsExceeded = AttemptsExceededAction.Delete instead of OnAttemptsExceeded = AttemptsExceededAction.Fail ?
I guess a job could go into Fail state several times regardless the numbers of attempts has exceeded or not? I tried to find any documentation about a job life cycle but could not find any… hence the question.
If I use the Delete state as you do, what happen if I really want to delete a job (manually via hangfire web interface)… wouldn’t the filter intercept my action and stop the deletion?
I know this is an old post but had similar questions myself, so thought I’d post answers for anyone else finding this thread now that I’ve been able to figure them out.
The answer is that if you use the OnStateElection the fail state is elected for each failed attempt (first and each retry) but if you use the OnStateApplied then the fail state is only called on the final fail, so checking for a failed state with OnAttemptsExceeded set to Fail will work.
Hooking into the OnStateApplied hasn’t caused the state to no longer get applied for me - although I’m not attempting to change it, just sending an email alert.