fix(api): DecompileController drops request CancellationToken into MediatR (CA2016) #665

Closed
opened 2026-07-17 16:23:08 +00:00 by spikerj · 1 comment
Owner

The four DecompileController actions (UploadDll, GetDecompiledTree, GetDecompiledFile, GetFileMetadata) each accept a CancellationToken bound to HttpContext.RequestAborted and already thread it into ConvertFormFileToFileDataDto and stream.CopyToAsync — but called _mediator.Send(request) without it. MediatRs single-arg Send overload passes CancellationToken.None, so a client disconnect never cancelled the downstream handler pipeline. Abandoned requests (browser closed, gateway timeout) kept running DB reads and CPU-heavy decompilation to completion (CA2016).

Fix: forward the actions token to all four Send calls. Behavior on the happy path is unchanged; only cancellation now propagates.

Test: added GetDecompiledTree_ShouldForwardCancellationTokenToMediator asserting the specific token reaches the mediator. The existing tests used It.IsAny<CancellationToken>() and passed even with the bug, so they were not a guard.

Scope: SpikerSoft.Api/Domain/Decompile/DecompileController.cs + its test. dotnet build clean; all 16 DecompileController tests pass. SonarQube rule external_roslyn:CA2016.

The four `DecompileController` actions (`UploadDll`, `GetDecompiledTree`, `GetDecompiledFile`, `GetFileMetadata`) each accept a `CancellationToken` bound to `HttpContext.RequestAborted` and already thread it into `ConvertFormFileToFileDataDto` and `stream.CopyToAsync` — but called `_mediator.Send(request)` **without** it. MediatRs single-arg `Send` overload passes `CancellationToken.None`, so a client disconnect never cancelled the downstream handler pipeline. Abandoned requests (browser closed, gateway timeout) kept running DB reads and CPU-heavy decompilation to completion (CA2016). **Fix:** forward the actions token to all four `Send` calls. Behavior on the happy path is unchanged; only cancellation now propagates. **Test:** added `GetDecompiledTree_ShouldForwardCancellationTokenToMediator` asserting the specific token reaches the mediator. The existing tests used `It.IsAny<CancellationToken>()` and passed even with the bug, so they were not a guard. Scope: `SpikerSoft.Api/Domain/Decompile/DecompileController.cs` + its test. `dotnet build` clean; all 16 DecompileController tests pass. SonarQube rule external_roslyn:CA2016.
Author
Owner

Resolved in spikersoft-backend PR #365 (merged to master). Forwarded the request CancellationToken to all four _mediator.Send calls in DecompileController; added a regression test asserting the specific token reaches the mediator (CA2016). Unit tests + both-arch backend image builds green; merged past the queued create_manifest packaging / non-blocking notify steps. Closing.

Resolved in spikersoft-backend PR #365 (merged to `master`). Forwarded the request CancellationToken to all four _mediator.Send calls in DecompileController; added a regression test asserting the specific token reaches the mediator (CA2016). Unit tests + both-arch backend image builds green; merged past the queued create_manifest packaging / non-blocking notify steps. Closing.
Sign in to join this conversation.