Search code examples
c#.net-coreservice-workerquartz.netquartz

.NET Core Quartz retry job on exception


I have a .NET 5 worker service with Quartz and I've prepared a job that will execute every day at a specific time. However, there was an occurrence of an exception in the job Execute(IJobExecutionContext context) method. And due to the fact that I've just put a throw; in the method, the service continued to work normally, but it didn't re-trigger the job.

Program.cs:

services.AddQuartz(properties, options =>
{
    options.UseMicrosoftDependencyInjectionScopedJobFactory();
});
services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);

DailyJob.cs:

[DisallowConcurrentExecution]
public class DailyJob: IJob
{
    private readonly ILogger<DailyJob> _logger

    public DailyJob(
        ILogger<DailyJob> logger
        )
    {
        _logger = logger;
    }

    public Task Execute(IJobExecutionContext context)
    {
        try
        {
            // DoStuff
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, ex.Message);
            throw;
        }

        return Task.CompletedTask;
    }
}

Now, my question is if can I somehow avoid this by refiring the job right away? I've seen the type JobExecutionException with a parameter bool refireImmediately, but if I throw that exception, will it do anything? It's still an exception and I am throwing out of the Execute method.


Solution

  • I've found some helpful info here: Refire quartz.net trigger after 15 minutes if job fails with exception

    Should look like this:

    public Task Execute(IJobExecutionContext context)
    {
        try
        {
            // DoStuff
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, ex.Message);
            
            SimpleTriggerImpl retryTrigger = new SimpleTriggerImpl(Guid.NewGuid().ToString());      
            retryTrigger.Description = "RetryTrigger";
            retryTrigger.RepeatCount = 0;
            retryTrigger.JobKey = context.JobDetail.Key;   // connect trigger with current job      
            retryTrigger.StartTimeUtc = DateBuilder.NextGivenSecondDate(DateTime.Now, 30);  // Execute after 30 seconds from now
            context.Scheduler.ScheduleJob(retryTrigger);   // schedule the trigger
    
            JobExecutionException jex = new JobExecutionException(ex, false);
            throw jex;
        }
    
        return Task.CompletedTask;
    }