Open Closed

Exceptions thrown in the Local Event Bus is not handled as expected #6742


User avatar
0
JohnJonsson created

When an exception is thrown in ILocalEventhandler during a domain event like EntityCreatedEventData the response is Error: response status is 200 instead of an expected 500 internal server error. This problem seems to been present after the changes in how UOW works from this commit https://github.com/abpframework/abp/pull/9909.

In versions previous of this commit we where able to throw exceptions EntityCreatingEventData, EntityUpdatingEventData, EntityDeletingEventData and EntityChangingEventData. Which returned the correct Error message. We have been using these events for validation purposes to stop transactions without the need for overriding specific methods and returning UserFriendlyExceptions back to the clients.

This problem is also present when publishing events using the ILocalEventBus. If an exception is thrown in an user defined event the same Error: response status is 200 is returned. From what i can see the response back to the client is started before the UOW has been completed. Which from my point of view is not a desired behavior.

Now the clients don't get good error response and the logs gets muddled up with middleware exceptions.

  • ABP Framework version: v8.0.3
  • UI Type: Angular
  • Database System: EF Core (SQL Server)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace:
2024-02-26 08:17:19.471 +01:00 [INF] Executing ObjectResult, writing value of type 'Volo.Abp.Identity.IdentityUserDto'.
2024-02-26 08:17:19.472 +01:00 [INF] Executed action Volo.Abp.Identity.IdentityUserController.CreateAsync (Volo.Abp.Identity.Pro.HttpApi) in 225.3291ms
2024-02-26 08:17:19.472 +01:00 [INF] Executed endpoint 'Volo.Abp.Identity.IdentityUserController.CreateAsync (Volo.Abp.Identity.Pro.HttpApi)'
2024-02-26 08:17:19.472 +01:00 [DBG] Added 0 entity changes to the current audit log
2024-02-26 08:17:19.487 +01:00 [DBG] Added 0 entity changes to the current audit log
2024-02-26 08:17:19.488 +01:00 [DBG] Added 0 entity changes to the current audit log
2024-02-26 08:17:21.772 +01:00 [WRN] An exception occurred, but response has already started!
2024-02-26 08:17:21.775 +01:00 [ERR] An unhandled exception has occurred while executing the request.
System.NotImplementedException: The method or operation is not implemented.
   at AbpTest.Test.HandleEventAsync(EntityCreatedEventData`1 eventData) in C:\Workspaces\8.0.3\aspnet-core\src\abp803.Application\TestApp.cs:line 17
   at Volo.Abp.EventBus.LocalEventHandlerMethodExecutor`1.<>c.<get_ExecutorAsync>b__1_0(IEventHandler target, Object parameter)
   at Volo.Abp.EventBus.EventHandlerInvoker.InvokeAsync(IEventHandler eventHandler, Object eventData, Type eventType)
   at Volo.Abp.EventBus.Local.LocalEventBus.InvokeEventHandlerAsync(IEventHandler eventHandler, Object eventData, Type eventType)
   at Volo.Abp.EventBus.EventBusBase.TriggerHandlerAsync(IEventHandlerFactory asyncHandlerFactory, Type eventType, Object eventData, List`1 exceptions, InboxConfig inboxConfig)
   at System.AbpExceptionExtensions.ReThrow(Exception exception)
   at Volo.Abp.EventBus.EventBusBase.ThrowOriginalExceptions(Type eventType, List`1 exceptions)
   at Volo.Abp.EventBus.EventBusBase.TriggerHandlersAsync(Type eventType, Object eventData)
   at Volo.Abp.EventBus.Local.LocalEventBus.PublishAsync(LocalEventMessage localEventMessage)
   at Volo.Abp.EventBus.Local.LocalEventBus.PublishToEventBusAsync(Type eventType, Object eventData)
   at Volo.Abp.EventBus.Local.LocalEventBus.PublishAsync(Type eventType, Object eventData, Boolean onUnitOfWorkComplete)
   at Volo.Abp.EventBus.UnitOfWorkEventPublisher.PublishLocalEventsAsync(IEnumerable`1 localEvents)
   at Volo.Abp.Uow.UnitOfWork.CompleteAsync(CancellationToken cancellationToken)
   at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.&lt;&gt;c__DisplayClass2_0.&lt;&lt;CreateMiddleware&gt;b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.&lt;&gt;c__DisplayClass2_0.&lt;&lt;CreateMiddleware&gt;b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.&lt;&gt;c__DisplayClass2_0.&lt;&lt;CreateMiddleware&gt;b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpOpenIddictMiddlewareExtension.&lt;&gt;c__DisplayClass0_0.&lt;&lt;UseAbpOpenIddictValidation&gt;b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.&lt;&gt;c__DisplayClass2_0.&lt;&lt;CreateMiddleware&gt;b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.&lt;&gt;c__DisplayClass2_0.&lt;&lt;CreateMiddleware&gt;b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
2024-02-26 08:17:21.775 +01:00 [WRN] The response has already started, the error page middleware will not be executed.
2024-02-26 08:17:21.777 +01:00 [ERR] An unhandled exception has occurred while executing the request.
System.NotImplementedException: The method or operation is not implemented.
   at AbpTest.Test.HandleEventAsync(EntityCreatedEventData`1 eventData) in C:\Workspaces\8.0.3\aspnet-core\src\abp803.Application\TestApp.cs:line 17
   at Volo.Abp.EventBus.LocalEventHandlerMethodExecutor`1.&lt;&gt;c.&lt;get_ExecutorAsync&gt;b__1_0(IEventHandler target, Object parameter)
   at Volo.Abp.EventBus.EventHandlerInvoker.InvokeAsync(IEventHandler eventHandler, Object eventData, Type eventType)
   at Volo.Abp.EventBus.Local.LocalEventBus.InvokeEventHandlerAsync(IEventHandler eventHandler, Object eventData, Type eventType)
   at Volo.Abp.EventBus.EventBusBase.TriggerHandlerAsync(IEventHandlerFactory asyncHandlerFactory, Type eventType, Object eventData, List`1 exceptions, InboxConfig inboxConfig)
   at System.AbpExceptionExtensions.ReThrow(Exception exception)
   at Volo.Abp.EventBus.EventBusBase.ThrowOriginalExceptions(Type eventType, List`1 exceptions)
   at Volo.Abp.EventBus.EventBusBase.TriggerHandlersAsync(Type eventType, Object eventData)
   at Volo.Abp.EventBus.Local.LocalEventBus.PublishAsync(LocalEventMessage localEventMessage)
   at Volo.Abp.EventBus.Local.LocalEventBus.PublishToEventBusAsync(Type eventType, Object eventData)
   at Volo.Abp.EventBus.Local.LocalEventBus.PublishAsync(Type eventType, Object eventData, Boolean onUnitOfWorkComplete)
   at Volo.Abp.EventBus.UnitOfWorkEventPublisher.PublishLocalEventsAsync(IEnumerable`1 localEvents)
   at Volo.Abp.Uow.UnitOfWork.CompleteAsync(CancellationToken cancellationToken)
   at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpOpenIddictMiddlewareExtension.<>c__DisplayClass0_0.<<UseAbpOpenIddictValidation>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
   at Microsoft.WebTools.BrowserLink.Net.BrowserLinkMiddleware.InvokeAsync(HttpContext context)
   at Microsoft.AspNetCore.Watch.BrowserRefresh.BrowserRefreshMiddleware.InvokeAsync(HttpContext context)
   at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()
2024-02-26 08:17:21.777 +01:00 [WRN] The response has already started, the error page middleware will not be executed.
2024-02-26 08:17:21.778 +01:00 [ERR] Connection ID "18086456104325218355", Request ID "40000034-0000-fb00-b63f-84710c7967bb": An unhandled exception was thrown by the application.
System.NotImplementedException: The method or operation is not implemented.
   at AbpTest.Test.HandleEventAsync(EntityCreatedEventData`1 eventData) in C:\Workspaces\8.0.3\aspnet-core\src\abp803.Application\TestApp.cs:line 17
   at Volo.Abp.EventBus.LocalEventHandlerMethodExecutor`1.&lt;&gt;c.&lt;get_ExecutorAsync&gt;b__1_0(IEventHandler target, Object parameter)
   at Volo.Abp.EventBus.EventHandlerInvoker.InvokeAsync(IEventHandler eventHandler, Object eventData, Type eventType)
   at Volo.Abp.EventBus.Local.LocalEventBus.InvokeEventHandlerAsync(IEventHandler eventHandler, Object eventData, Type eventType)
   at Volo.Abp.EventBus.EventBusBase.TriggerHandlerAsync(IEventHandlerFactory asyncHandlerFactory, Type eventType, Object eventData, List`1 exceptions, InboxConfig inboxConfig)
   at System.AbpExceptionExtensions.ReThrow(Exception exception)
   at Volo.Abp.EventBus.EventBusBase.ThrowOriginalExceptions(Type eventType, List`1 exceptions)
   at Volo.Abp.EventBus.EventBusBase.TriggerHandlersAsync(Type eventType, Object eventData)
   at Volo.Abp.EventBus.Local.LocalEventBus.PublishAsync(LocalEventMessage localEventMessage)
   at Volo.Abp.EventBus.Local.LocalEventBus.PublishToEventBusAsync(Type eventType, Object eventData)
   at Volo.Abp.EventBus.Local.LocalEventBus.PublishAsync(Type eventType, Object eventData, Boolean onUnitOfWorkComplete)
   at Volo.Abp.EventBus.UnitOfWorkEventPublisher.PublishLocalEventsAsync(IEnumerable`1 localEvents)
   at Volo.Abp.Uow.UnitOfWork.CompleteAsync(CancellationToken cancellationToken)
   at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpOpenIddictMiddlewareExtension.<>c__DisplayClass0_0.<<UseAbpOpenIddictValidation>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
   at Microsoft.WebTools.BrowserLink.Net.BrowserLinkMiddleware.InvokeAsync(HttpContext context)
   at Microsoft.AspNetCore.Watch.BrowserRefresh.BrowserRefreshMiddleware.InvokeAsync(HttpContext context)
   at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()
2024-02-26 08:17:21.778 +01:00 [INF] Request finished HTTP/2 POST https://localhost:44392/api/identity/users - 200 null application/json; charset=utf-8 2537.4787ms
  • Steps to reproduce the issue:
  1. Create a new project abp new demo -u angular
  2. Create a new class which implements ILocalEventHandler&lt;EntityCreatedEventData&lt;IdentityUser&gt;> and throw an exception
    public class Test : ILocalEventHandler&lt;EntityCreatedEventData&lt;IdentityUser&gt;>, ITransientDependency
    {
        public Task HandleEventAsync(EntityCreatedEventData&lt;IdentityUser&gt; eventData)
        {
            throw new NotImplementedException();
        }
    }
  1. Create a new user ether from swagger or the UI

8 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you try to remove the app.UseUnitOfWork(); from your asp net core pipeline?

  • User Avatar
    0
    JohnJonsson created

    Hi

    Yes that worked. Now the correct error is returned end the exceptions is correctly described in the logs.

    What other implications is there when i remove this app.UseUnitOfWork();

    BR John

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    https://github.com/abpframework/abp/issues/15816 https://github.com/abpframework/abp/issues/10568

  • User Avatar
    0
    JohnJonsson created

    Hi

    It was quite hard to follow what app.UseUnitOfWork(); exactly is doing from the links. From what i read i does not seems to be necessary to include this anymore.

    I assume there no documentation on what the UseUnitOfWork middelware is doing?

    BR John

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    If you remove the UseUnitOfWork, the transaction becomes action scoped (or page handler scoped). We can not create a scope that covers multiple middlewares. As a result, there is no way to include audit logging into the transaction, which can be important for some companies.

    https://github.com/abpframework/abp/issues/10568#issue-1048233070

  • User Avatar
    0
    JohnJonsson created

    Hi

    I don't know if i follow you. The auditing is still working after i removed the UseUnitOfWork, What does it mean that "there is no way to include audit logging into the transaction"? My impression was that UseAuditing was handling all the auditing. My audit logs is written when a transaction is completed and not if an exception is thrown and the transaction is rolled back.

    BR John

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Audit logging can work just there is no same transactions. You can ignore it.

  • User Avatar
    0
    JohnJonsson created

    Ok

    thank you for the answers.

    BR John

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11