postgresqlasp.net-coreasp.net-web-apihangfireemail-notifications

How to perform an action after a hangfire background job fails and exhaust its max number of retries


I have an operation being performed as Hangfire background job like this:

var jobId = BackgroundJob.Enqueue(() => PerformActionA(param1, param2));

If the job with jobId gets failed and made max number of retries, I want to make an email notification:

NotifyUser.NotifyAboutFailedPerformActionAsync();

How do I perform this notification service after that job gets failed? There are various jobs that I am creating so I want to perform this email notification only for this operation PeformActionA.

I am new to Hangfire.


Solution

  • You could try following code works to apply a global filter. Assume you have the job is like

            [AutomaticRetry(Attempts = 3, OnAttemptsExceeded = AttemptsExceededAction.Fail)]
            public void PerformActionA(string userName,int userId)
            {
    
                throw new Exception("failure");
            }
    

    Then you could create a global filter like following

        public class JobFailureFilter : IApplyStateFilter
        {
            public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
            {
                string methodName = context.BackgroundJob.Job.Method.Name;
                if (methodName == "PerformActionA")
                {
                    if (context.NewState is FailedState failedState)
                    {
                        string userName = (string)context.BackgroundJob.Job.Args[0];
                        int userId = (Int32)context.BackgroundJob.Job.Args[1];
    
                        NotifyUser.NotifyAboutFailedPerformActionAsync(userName,userId);
                    }
                }
            }
    
            public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
            {
    
            }
    
        }
    

    Then apply this filter to program.cs

    builder.Services.AddHangfire(x=> {
        x.UseSqlServerStorage(xxx);
    });
    GlobalJobFilters.Filters.Add(new JobFailureFilter());