Search code examples
castle-windsorquartz.net

Quartz.NET doesn't throw exception if job instantiation fails


I am using Quartz.NET via castle windsor, everything works fine but one of job used Identity dependency and If I do not registered dependency it doesn't throw exception.

registration code

 static void RegisterTriggerListeners(IWindsorContainer container)
    {
        container.Register(DefaultInterfaces());
        container.Register(Connections());
        container.Register(
            Component.For<Quartz.IScheduler>().Instance(StdSchedulerFactory.GetDefaultScheduler()),
            Component.For<IJobFactory>().ImplementedBy<WindsorJobFactory>().DependsOn(Dependency.OnValue<IWindsorContainer>(container)).LifestyleTransient(),

            // See: http://blog.nikosbaxevanis.com/2012/07/16/using-the-web-api-dependency-resolver-with-castle-windsor-scoped-lifetime/
            // public void Install(IWindsorContainer container, IConfigurationStore store) section near the end of the page
            Classes.FromThisAssembly().BasedOn<IHttpController>().LifestyleScoped()
            //,
            //Component
            //  .For<IIdentity>()
            //  .UsingFactoryMethod(WindowsIdentity.GetCurrent)
            //  .LifestyleSingleton()
            );

        RegisterJobs(container);
    }

job that use Identity

class ValidationStep : Step<ITransactionLineValidationStep, TransactionLine>, ITransactionLineValidationStep
    {
        private IImpersonatedWebClient ImpersonatedWebClient { get; }
        private ISettings Settings { get; }
        readonly IIdentity _identity;
        private string ValidationAddress { get; set; }
        private const string ValidationResultError = "Error";

        public ValidationStep(IImpersonatedWebClient impersonatedWebClient,
            ISettings settings,
            IIdentity identity)
        {
            ImpersonatedWebClient = impersonatedWebClient;
            Settings = settings;
            _identity = identity;
        }

if I commented out Identity registration - scheduler is running fine but stops running using job without throwing exception. Is there any way I get notified or throw exception if dependency are not registered ?


Solution

  • It's probably not Castle issue as Castle always throws exception when some non-optional (constructor) dependency is missing during component resolving.

    What you see is result of Quartz.NET design - if exception is thrown during job creation (using job factory method NewJob), Quartz just catch it and convert it to SchedulerException (see JobRunShell line 94) which is later swalowed (see QuartzSchedulerThread line 420). At the same time, Quartz invokes SchedulerError method of any ISchedulerListener attached to it's scheduler

    Reason for all this is to protect Quartz scheduler thread from breaking the application. If you only want to check this during development, just configure Quartz logging (uses Common.Logging framework - see documentation - at the bottom) and you'll see errors like this in log. Otherwise you can write your own ISchedulerListener to handle SchedulerError "event" and do whatever you want there...

    Note: Source code links provided are from master branch, which is for yet unreleased 3.x version of Quartz.NET but 2.x version works same...