c# - Manejar JobExecutionException en Quartz.net
exception-handling (3)
Como ya se mencionó, la forma correcta de "detectar" las JobExecutionException a nivel global es implementar y registrar un IJobListener y verificar si el parámetro JobExecutionException en el método JobWasExecuted () es! = Null.
Sin embargo, el problema que tuve (y a juzgar por el comentario adicional del OP, él también enfrentó esto) fue que Quartz no manejó la JobExecutionException (como debería) que resultó en una excepción no controlada que mató la aplicación.
Hasta ahora, estaba usando la DLL precompilada del paquete Quartz.NET 2.0.1 release (.NET3.5). Para llegar al fondo del problema, me referí al proyecto / sourcecode de Quartz y, para mi sorpresa, ¡¿de repente estaba funcionando ?!
Como punto de interés, este es el código de la biblioteca de Quartz que ejecuta el IJob y maneja la excepción JobExecutionException:
try {
if (log.IsDebugEnabled) {
log.Debug("Calling Execute on job " + jobDetail.Key);
}
job.Execute(jec);
endTime = SystemTime.UtcNow();
} catch (JobExecutionException jee) {
endTime = SystemTime.UtcNow();
jobExEx = jee;
log.Info(string.Format(CultureInfo.InvariantCulture, "Job {0} threw a JobExecutionException: ", jobDetail.Key), jobExEx);
} catch (Exception e) {
// other stuff here...
}
Lo siguiente fue hacer referencia directamente a mi DLL recién compilada y esto también funcionó. Lamentablemente, no puedo decir por qué funciona esto y actualmente no tengo tiempo para continuar, pero quizás esto ayude a alguien. Tal vez algún otro pueda confirmar esto e incluso aportar una explicación. ¿Puede tener algo que ver con diferentes plataformas de destino (x86 / 64bit)?
Probablemente una pregunta estúpida ... pero aquí va de todos modos ...
He configurado cuarzo y puedo programar trabajos, y puedo confirmar que los trabajos (implementando la interfaz IJob) están funcionando.
Mirando la documentación en el sitio, (Lección 3 del tutorial):
El único tipo de excepción que se le permite lanzar desde el método de ejecución es
JobExecutionException
.
Me gustaría que cuando ocurra una excepción que no he manejado explícitamente, debería lanzar una excepción JobExecutionException, de modo que pueda iniciar sesión en la aplicación ''principal''. Envolví mi código en un retén de prueba y lancé la excepción JobExecutionException, ¿pero ahora dónde manejarlo?
No llamo al método de ejecución en ningún lugar, que es manejado por Quartz (en un hilo separado). Entonces, ¿cómo manejo ese error cuando ocurre? Realmente no quiero tragar el error en el trabajo
Normalmente, configuraría el método de ejecución de su trabajo de la siguiente manera:
try
{
// the work you want to do goes here
}
catch (ExceptionTypeYouWantToHandle1 ex1)
{
// handle exception
}
catch (ExceptionTypeYouWantToHandle2 ex2)
{
// handle exception
}
// and so on
catch (Exception ex)
{
// something really unexpected happened, so give up
throw new JobExecutionException("Something awful happened", ex, false); // or set to true if you want to refire
}
En este punto, el programador registrará la excepción en cualquier lugar donde se registre (según la configuración).
Resolví este problema usando una clase base para detectar todas las excepciones:
public abstract class JobBase : IJob
{
protected JobBase()
{
}
public abstract void ExecuteJob(JobExecutionContext context);
public void Execute(JobExecutionContext context)
{
string logSource = context.JobDetail.FullName;
try
{
ExecuteJob(context);
}
catch (Exception e)
{
// Log exception
}
}
}
A tu clase de trabajo le debería gustar esto:
public class SomeJob : JobBase
{
public SomeJob()
{
}
public override void ExecuteJob(JobExecutionContext context)
{
// Do the actual job here
}
}