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.)
Details changed:
Expand ›
Details changed:
Expand ›
Summary changed:
Expand ›
see also: relevant discussion
Project
Iceshrimp.NETPriority
NormalN
Type
BugB
State
UntriagedU
Assignee
LilianSubsystem
FrontendF
Component
No componentAffected version
UnknownTarget version
UnscheduledReleased in version
Unreleased
oh yeah solving this on the frontend sounds like a much better idea