9

I am currently working on EmailNotification module in which i have started using hangfire. The only issue is after trying 10 times, if hangfire fails to (schedule job) email in my case, there is not way i can find to get updates regarding that via code.

I know of the fact, i can access hangfire - dashboard by configuring hangfire as below:

public void ConfigureHangfire(IAppBuilder app)
{
    var container = AutofacConfig.RegisterBackgroundJobComponents();
    var sqlOptions = new SqlServerStorageOptions
    {
        PrepareSchemaIfNecessary = Config.CreateHangfireSchema
    };
    Hangfire.GlobalConfiguration.Configuration.UseSqlServerStorage("hangfire", sqlOptions);
    Hangfire.GlobalConfiguration.Configuration.UseAutofacActivator(container);
    var options = new BackgroundJobServerOptions() {Queues = new[] {"emails"}};
    app.UseHangfireDashboard();
    app.UseHangfireServer(options);
}

But the issue is i am not able to find a way to access failed job programmatically. I wonder if anyone has come across this issue, would like to know details.

vran
  • 163
  • 3
  • 11
  • Try here: http://docs.hangfire.io/en/latest/background-processing/dealing-with-exceptions.html Look for "Can we create a custom exception handler". Maybe this will help. i didn't make this an answer, cause I'm not sure. – Xavier J May 25 '16 at 19:06
  • Logic to access failed jobs based on custom exception, i am not sure if i like that idea. However, i am looking into it - if i find something handy - will update here - Thanks! – vran May 25 '16 at 19:13

1 Answers1

11

You can use Hangfire Job Filters for this. Job filter allows you to extend functionality of hangfire, and you can do many interesing things with them (See the official documentation here for more details)

Create a class that extends from JobFilterAttribute

And then implement IElectStateFilter interface. This interface provides you with a method, OnStateElection which is called when the current state of the job is being changed to the specified candidate state, say FailedState.

public class MyCustomFilter : JobFilterAttribute, IElectStateFilter
{
    public void IElectStateFilter.OnStateElection(ElectStateContext context)
    {
        var failedState = context.CandidateState as FailedState;
        if (failedState != null)
        {
            //Job has failed
            //Job ID => context.BackgroundJob.Id,
            //Exception => failedState.Exception
        }
    }
}

And then, register this attribute -

GlobalJobFilters.Filters.Add(new MyCustomFiler());

If you need to capture event, after the state is applied, you can implement IApplyStateFilter instead.

Vinyl Warmth
  • 2,226
  • 3
  • 25
  • 50
Yogi
  • 9,174
  • 2
  • 46
  • 61
  • Thanks - That worked!! The only thing is it's async so i wouldn't know instantly what to display on UI - but i guess, for now i am just using three different states like - IN PROGRESS - FINISHED - FAILED - till i get a confirmation of Finished or Failed, i will just use IN PROGRESS as status for that job!! – vran May 26 '16 at 21:27
  • 1
    With hangfire 1.6.x I experienced that `OnStateElection` would say `failed` even though the retry count was not fully exhausted yet. Not sure whether that is by design, but for my purpose (notify when actually failed and no more retries) the `IApplyStateFilter` did it. – nover Aug 15 '19 at 13:36