ISH-646
Created by Jo
1 year ago
Nov 28 2024, 13:09 GMT+1
Updated by Laura Hausmann
1 year ago
Nov 28 2024, 18:22 GMT+1
Clicking send follow request rapidly causes frontend crash

I was met with this traceback;

iceshrimp.net_web  | fail: [0HN8FK5DGM12K:00000001] EntityFramework.Exceptions.Common.ExceptionProcessorInterceptor`1:
iceshrimp.net_web  |       Request encountered an unexpected error: EntityFramework.Exceptions.Common.UniqueConstraintException: Unique constraint violation
iceshrimp.net_web  |        ---> Npgsql.PostgresException (0x80004005): 23505: duplicate key value violates unique constraint "IX_follow_request_followerId_followeeId"
iceshrimp.net_web  |
iceshrimp.net_web  |       DETAIL: Detail redacted as it may contain sensitive data. Specify 'Include Error Detail' in the connection string to include this information.
iceshrimp.net_web  |          at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
iceshrimp.net_web  |          at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
iceshrimp.net_web  |          at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
iceshrimp.net_web  |         Exception data:
iceshrimp.net_web  |           Severity: ERROR
iceshrimp.net_web  |           SqlState: 23505
iceshrimp.net_web  |           MessageText: duplicate key value violates unique constraint "IX_follow_request_followerId_followeeId"
iceshrimp.net_web  |           Detail: Detail redacted as it may contain sensitive data. Specify 'Include Error Detail' in the connection string to include this information.
iceshrimp.net_web  |           SchemaName: public
iceshrimp.net_web  |           TableName: follow_request
iceshrimp.net_web  |           ConstraintName: IX_follow_request_followerId_followeeId
iceshrimp.net_web  |           File: nbtinsert.c
iceshrimp.net_web  |           Line: 664
iceshrimp.net_web  |           Routine: _bt_check_unique
iceshrimp.net_web  |          --- End of inner exception stack trace ---
iceshrimp.net_web  |          at EntityFramework.Exceptions.Common.ExceptionProcessorInterceptor`1.SaveChangesFailedAsync(DbContextErrorEventData eventData, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Microsoft.EntityFrameworkCore.Diagnostics.CoreLoggerExtensions.SaveChangesFailedAsync(IDiagnosticsLogger`1 diagnostics, DbContext context, Exception exception, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
iceshrimp.net_web  |          at Iceshrimp.Backend.Core.Services.UserService.FollowUserAsync(User follower, User followee, String requestId) in /_/Iceshrimp.Backend/Core/Services/UserService.cs:line 815
iceshrimp.net_web  |          at Iceshrimp.Backend.Controllers.Web.UserController.FollowUser(String id) in /_/Iceshrimp.Backend/Controllers/Web/UserController.cs:line 141
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
iceshrimp.net_web  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
iceshrimp.net_web  |          at Iceshrimp.Backend.Core.Middleware.AuthorizationMiddleware.InvokeAsync(HttpContext ctx) in /_/Iceshrimp.Backend/Core/Middleware/AuthorizationMiddleware.cs:line 41
iceshrimp.net_web  |          at Microsoft.AspNetCore.RateLimiting.RateLimitingMiddleware.InvokeInternal(HttpContext context, EnableRateLimitingAttribute enableRateLimitingAttribute)
iceshrimp.net_web  |          at Iceshrimp.Backend.Core.Middleware.AuthenticationMiddleware.InvokeAsync(HttpContext ctx, RequestDelegate next) in /_/Iceshrimp.Backend/Core/Middleware/AuthenticationMiddleware.cs:line 116
iceshrimp.net_web  |          at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
iceshrimp.net_web  |       --- End of stack trace from previous location ---
iceshrimp.net_web  |          at Iceshrimp.Backend.Core.Middleware.RequestVerificationMiddleware.InvokeAsync(HttpContext ctx, RequestDelegate next) in /_/Iceshrimp.Backend/Core/Middleware/RequestVerificationMiddleware.cs:line 22
iceshrimp.net_web  |          at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
iceshrimp.net_web  |       --- End of stack trace from previous location ---
iceshrimp.net_web  |          at Iceshrimp.Backend.Core.Middleware.ErrorHandlerMiddleware.InvokeAsync(HttpContext ctx, RequestDelegate next) in /_/Iceshrimp.Backend/Core/Middleware/ErrorHandlerMiddleware.cs:line 32

And this user-supplied log;

Connection failed: TaskCanceledException_ctor_DefaultMessageSuccessfully fetched backend version.Successfully fetched backend version.Successfully fetched backend version.Successfully fetched backend version.Successfully fetched backend version.Successfully fetched backend version.Successfully fetched backend version.Successfully fetched backend version.Iceshrimp.Frontend.Core.Miscellaneous.ApiException: Exception_WasThrown, Iceshrimp.Frontend.Core.Miscellaneous.ApiException
   at Iceshrimp.Frontend.Core.Services.ApiClient.CallNullableAsync(HttpMethod method, String path, Nullable`1 query, Object data)
   at Iceshrimp.Frontend.Components.FollowButton.Follow()
   at Iceshrimp.Frontend.Components.FollowButton.Action()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task , ComponentState )Successfully fetched backend version.

However, the user quickly noted this afterwards;

it only crashed once but it also managed to send the api request, so it must've been afterwards that caused the crash

do note that my mouse is troublesome and sometimes clicks twice

So it is possible that this user accidentally clicked twice, having the backend fire two api calls to send the follow request twice.


(This issue could be generalised to a general issue that the buttons on the frontend don't "lock themselves out" if they're clicked, until the associated request(s) are finished.)

Avatar
Details changed: Expand ›
Avatar
Details changed: Expand ›
Avatar
Summary changed: Expand ›
Avatar

oh yeah solving this on the frontend sounds like a much better idea

Project
Iceshrimp.NET
Priority
Normal
N
Type
Bug
B
State
Untriaged
U
Assignee
Lilian
Avatar
Subsystem
Frontend
F
Component
No component
Affected version
Unknown
Target version
Unscheduled
Released in version
Unreleased