Search code examples
c#hangfire

Get a parameter of a job in Hangfire job filter when Job Failed


In order to send emails when job fails I'm trying to implement something like this : Hangfire send emails after retry .

But I need to access a parameter of the job method performed. This parameter corresponds to an ID of a company, and I need this idea in order to know which connectionString should i use to access db.

I need to access a DB here to know if we have already sent an email for the current job (in order to not spam emails everytime the same job fails).

So i would have something like this :

  • Job A Runs
  • Job A Fails
  • Job A Filter is executed,
    • Job A Filter Check in db if email has been already sent for this job
      • If not send an email to admins
      • Put a record in db to indicate that an email has been sent for this job
  • Job A Runs
  • Job A Fails
  • Job A Filter is executed again
    • Job A filter won't send an email because it has been already sent Etc...

I don't know if it's the correct approach to go for, if you guys have any idea to improve that, feel free !

But still, my question is can i access to a parameter of the executed job method to know that company id ? Or is there any way to provide datas from job method to an AttributeFilter (like bags etc...) when a job fails to execute?

Thanks for reading me !


Solution

  • I would try something like this with an IApplyStateFilter

    public class NotifyExceptionsServerFilter : IApplyStateFilter
    {
        public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
        {
    
            var c = context.NewState as FailedState;
            if (c?.Exception != null && context.Job.Method.Name == "YourMethodName")
            {
                var companyId = context.Job.Args[CompanyIdArgumentIndexInYourMethodSignature];
    
                // Do stuff using CompanyId
            }
        }
    
        public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
        {
        }
    }
    

    This is roughly the idea. Would it work, it will need at least to be secured with specific tests preventing errors caused by refactoring, as it relies on Reflection.