We are implementing custom exception handling for our project.
We've implemented IAsyncEventHandler<AbpHandledExceptionData>
for AppServices and IAsyncExceptionFilter
for Controllers and everything works fine, these areas are covered.
We also have a lot of IAsyncEventHandler
governed by hangfire for different background events.
The problem is that if an exception occurs inside HandleEventAsync
, neither handler nor filter get triggered.
Is there any way to handle these exceptions?
We have tried following (nothing worked):
- creating custom
ExceptionFilterAttribute
and attaching it to the instance ofIAsyncExceptionFilter
, attribute never gets called. - monitoring
AbpHandledExceptionData
, never gets called. - monitoring
EntityCreatedEventData<AuditLog>
doesn't work because audit log is not written in this case. - monitoring
EntityCreatedEventData<SqlJob>
doesn't work becauseHangfire.SqlJob
is not public like audit log. - using custom logger for hangfire doesn't do anything, the logger never gets called:
Startup:
services.AddHangfire(config =>
{
config.UseSqlServerStorage(_appConfiguration.GetConnectionString("Default"));
config.UseFilter(new AutomaticRetryAttribute
{
Attempts = 2,
OnAttemptsExceeded = AttemptsExceededAction.Fail,
LogEvents = true,
});
config.UseLogProvider(new CustomLog4NetLogProvider()); // doesn't work
});
Custom logger:
public class CustomLog4NetLogProvider : Log4NetLogProvider
{
public new ILog GetLogger(string name)
{
return new CustomLog4NetLogger(base.GetLogger(name));
}
}
public class CustomLog4NetLogger : ILog
{
private readonly ILog _baseLogger;
public CustomLog4NetLogger(ILog baseLogger)
{
_baseLogger = baseLogger;
}
public bool Log(LogLevel logLevel, Func<string> messageFunc, Exception exception = null)
{
// do something
return _baseLogger.Log(logLevel, messageFunc, exception);
}
}
6 Answer(s)
-
0
Hi @ITWebTeam
IAsyncEventHandler
is mostly used to handle domain events, do you trigger an event when you catch an exception ?IAsyncEventHandler
can be used in the same way for background jobs. If you can share the code blocks for;- trowing the exception
- handling the exception in IAsyncEventHandler we can take a look at this.
-
0
Hi @ismcagdas and thank you for the reply.
In most cases we don't catch the exceptions, we rely on the framework to handle this for us. In the case of background jobs we are depending on the exceptions details getting logged to the Audit log. We are trying to add functionality to send a notification whenever an exception is thrown. However, we are not receiving any events through AbpHandledExceptionData for background jobs wo no notifications are being sent nor are they logged in the audit log. It works for everything else. Below is an example of the workflow.
Enqueueing event:
// _backgroundJobManager is IBackgroundJobManager injected into an AppService's constructor. await _backgroundJobManager.EnqueueEventAsync(new ProductFieldApprovedEventData { // properties });
Handling event and throwing the exception inside:
public class WebhookPublishProductFieldApproved : ISingletonDependency, IAsyncEventHandler<ProductFieldApprovedEventData> { // other dependencies public async Task HandleEventAsync(ProductFieldApprovedEventData eventData) { throw new System.Exception("test from background job"); // cannot catch this later using handlers // actual logic for this event's handling } }
Handling the exception event:
public class ExceptionWebhookEventHandler : ISingletonDependency, IAsyncEventHandler<AbpHandledExceptionData> { // other dependencies public async Task HandleEventAsync(AbpHandledExceptionData eventData) { // handling logic using eventData.Exception } }
-
0
Hi,
Thanks. Could you also share
ProductFieldApprovedEventData
or where it throws the exception ? -
0
Hi,
You can see in the prior example we are throwing a test exception in the
WebhookPublishProductFieldApproved
class which throws this:throw new System.Exception("test from background job");
It runs in the background. We want to handle any exception that are thrown in the background.
Below is the
ProductFieldApprovedEventData
classpublic class ProductFieldApprovedEventData : WebhookEventData { public int ProductId { get; set; } public int ProductDetailId { get; set; } } public class WebhookEventData : EventData { public SchemaTypeEnum SchemaType { get; set; } }
Thank you
-
0
Hi @ITWebTeam
Thanks, @oguzhanagir is working on this problem and will inform you.
-
0
Hi @ITwebTeam,
When we tested the parts you shared with us, we didn't encounter the specified problem. You can share the project with us so we can help you more. You can send the project to [email protected].