Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception happening during IJob resolving isn't propagated to IExceptionHandler, nor IJobNotificationHandler #177

Open
nulltoken opened this issue Jan 25, 2025 · 3 comments · May be fixed by #179
Assignees
Labels
bug Something isn't working

Comments

@nulltoken
Copy link
Collaborator

nulltoken commented Jan 25, 2025

Describe the bug
Given the following setup

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NCronJob;
using RunOnceSample;

internal class Program
{
    private static async Task Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddNCronJob(options =>
        {
            options.AddJob<JobThatThrowsInCtor>((jo) => jo.WithCronExpression("* * * * *")).AddNotificationHandler<NotifyHandler>();
            options.AddExceptionHandler<ExHandler>();
        });


        var app = builder.Build();

        var progressReporter = app.Services.GetRequiredService<IJobExecutionProgressReporter>();

        progressReporter.Register(Subscriber);

        await app.UseNCronJobAsync();

        await app.RunAsync();
    }

    private static void Subscriber(ExecutionProgress progress)
    {
        Console.WriteLine($"{progress.Timestamp} {progress.CorrelationId} {progress.State}");
    }
}

internal class NotifyHandler : IJobNotificationHandler<JobThatThrowsInCtor>
{
    public Task HandleAsync(IJobExecutionContext context, Exception? exception, CancellationToken cancellationToken)
    {
        Console.WriteLine($"NotifyHandler: {exception}");
        return Task.CompletedTask;
    }
}

public class ExHandler : IExceptionHandler
{
    public Task<bool> TryHandleAsync(IJobExecutionContext jobExecutionContext, Exception exception, CancellationToken cancellationToken)
    {
        Console.WriteLine($"ExHandler: {exception}");
        return Task.FromResult(true);
    }
}

public sealed class JobThatThrowsInCtor : IJob
{
    public JobThatThrowsInCtor()
    {
        throw new Exception("Boom");
    }

    public Task RunAsync(IJobExecutionContext context, CancellationToken token)
    {
        // Should never reach this point

        return Task.CompletedTask;
    }
}

The folllowing output is produced

09:01:06 trce: NCronJob.JobWorker[1646325880] Next run of job 'JobThatThrowsInCtor' is at 2025-01-25T09:02:00.0000000+01:00
2025-01-25 09:01:06 +01:00 ce034462-1921-43b3-a763-544e6734d26c OrchestrationStarted
2025-01-25 09:01:06 +01:00 ce034462-1921-43b3-a763-544e6734d26c NotStarted
09:01:11 info: NCronJob.QueueWorker[1048409946] Job added to queue: JobThatThrowsInCtor at 2025-01-25T08:02:00.0000000+00:00
2025-01-25 09:01:15 +01:00 ce034462-1921-43b3-a763-544e6734d26c Scheduled
09:01:15 info: Microsoft.Hosting.Lifetime[14] Now listening on: http://localhost:5000
09:01:15 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down.
09:01:15 info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development
09:01:15 info: Microsoft.Hosting.Lifetime[0] Content root path: D:\Code\NCronJob\sample\RunOnceSample
09:02:00 info: NCronJob.QueueWorker[1034012635] Job removed from queue: JobThatThrowsInCtor at 2025-01-25T08:02:00.0000000+00:00
09:02:00 trce: NCronJob.JobWorker[1646325880] Next run of job 'JobThatThrowsInCtor' is at 2025-01-25T09:03:00.0000000+01:00
2025-01-25 09:02:00 +01:00 682448fb-6b0b-4498-a709-fc4e48f5f0a2 OrchestrationStarted
2025-01-25 09:02:00 +01:00 682448fb-6b0b-4498-a709-fc4e48f5f0a2 NotStarted
09:02:00 info: NCronJob.QueueWorker[1048409946] Job added to queue: JobThatThrowsInCtor at 2025-01-25T08:03:00.0000000+00:00
2025-01-25 09:02:00 +01:00 682448fb-6b0b-4498-a709-fc4e48f5f0a2 Scheduled
2025-01-25 09:02:00 +01:00 ce034462-1921-43b3-a763-544e6734d26c Initializing
2025-01-25 09:03:27 +01:00 ce034462-1921-43b3-a763-544e6734d26c Faulted
2025-01-25 09:03:27 +01:00 ce034462-1921-43b3-a763-544e6734d26c OrchestrationCompleted
09:03:31 info: NCronJob.QueueWorker[1034012635] Job removed from queue: JobThatThrowsInCtor at 2025-01-25T08:03:00.0000000+00:00
09:03:31 trce: NCronJob.JobWorker[1646325880] Next run of job 'JobThatThrowsInCtor' is at 2025-01-25T09:04:00.0000000+01:00
2025-01-25 09:03:31 +01:00 682448fb-6b0b-4498-a709-fc4e48f5f0a2 Initializing
2025-01-25 09:03:31 +01:00 e01bbeee-ea96-416b-8cb5-ca23972d8dd5 OrchestrationStarted
2025-01-25 09:03:31 +01:00 e01bbeee-ea96-416b-8cb5-ca23972d8dd5 NotStarted
09:03:31 info: NCronJob.QueueWorker[1048409946] Job added to queue: JobThatThrowsInCtor at 2025-01-25T08:04:00.0000000+00:00
2025-01-25 09:03:31 +01:00 e01bbeee-ea96-416b-8cb5-ca23972d8dd5 Scheduled
2025-01-25 09:03:31 +01:00 682448fb-6b0b-4498-a709-fc4e48f5f0a2 Faulted
2025-01-25 09:03:31 +01:00 682448fb-6b0b-4498-a709-fc4e48f5f0a2 OrchestrationCompleted
09:04:00 info: NCronJob.QueueWorker[1034012635] Job removed from queue: JobThatThrowsInCtor at 2025-01-25T08:04:00.0000000+00:00
09:04:00 trce: NCronJob.JobWorker[1646325880] Next run of job 'JobThatThrowsInCtor' is at 2025-01-25T09:05:00.0000000+01:00
2025-01-25 09:04:00 +01:00 e01bbeee-ea96-416b-8cb5-ca23972d8dd5 Initializing
2025-01-25 09:04:00 +01:00 f971b2ce-17a5-4fcf-9260-466f96be28bf OrchestrationStarted
2025-01-25 09:04:00 +01:00 f971b2ce-17a5-4fcf-9260-466f96be28bf NotStarted
09:04:00 info: NCronJob.QueueWorker[1048409946] Job added to queue: JobThatThrowsInCtor at 2025-01-25T08:05:00.0000000+00:00
2025-01-25 09:04:00 +01:00 f971b2ce-17a5-4fcf-9260-466f96be28bf Scheduled
2025-01-25 09:04:00 +01:00 e01bbeee-ea96-416b-8cb5-ca23972d8dd5 Faulted
2025-01-25 09:04:00 +01:00 e01bbeee-ea96-416b-8cb5-ca23972d8dd5 OrchestrationCompleted
09:05:00 info: NCronJob.QueueWorker[1034012635] Job removed from queue: JobThatThrowsInCtor at 2025-01-25T08:05:00.0000000+00:00

Current behavior
ExHandler is never notified, nor is NotifyHandler

Expected behavior

  • Both handlers get a peek at the exception.
  • Dependent jobs that should run, if the parent fails, probably will also not run in this scenario.

Version information

  • NCronJobVersion: latest
  • .NET runtime version: 9.0
@nulltoken nulltoken changed the title Exception happening during IJob resolving aren't propagated to IExceptionHandler, nor IJobNotificationHandler Exception happening during IJob resolving isn't propagated to IExceptionHandler, nor IJobNotificationHandler Jan 25, 2025
@linkdotnet
Copy link
Member

That is a very good point. I guess we can even go further here: Dependent jobs that should run, if the parent fails, probably will also not run in this scenario.

@nulltoken
Copy link
Collaborator Author

That is a very good point. I guess we can even go further here: Dependent jobs that should run, if the parent fails, probably will also not run in this scenario.

Updated Expected behavior in the description

@linkdotnet linkdotnet self-assigned this Jan 25, 2025
@linkdotnet
Copy link
Member

Working on it right now

@linkdotnet linkdotnet linked a pull request Jan 25, 2025 that will close this issue
@linkdotnet linkdotnet added the bug Something isn't working label Jan 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants