{"record":{"id":"cfab00f64b10808b","repo":"dotnet/runtime","slug":"operationcanceledexception","errorCode":null,"errorMessage":"OperationCanceledException","messagePattern":"OperationCanceledException","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/mono/browser/runtime/http.ts","lineNumber":260,"sourceCode":"    const view = new Span(bufferPtr, bufferLength, MemoryViewType.Byte);\n    return wrap_as_cancelable_promise(async () => {\n        await controller.responsePromise;\n        mono_assert(controller.response, \"expected response\");\n        if (!controller.response.body) {\n            // in FF when the verb is HEAD, the body is null\n            return 0;\n        }\n        if (!controller.streamReader) {\n            controller.streamReader = controller.response.body.getReader();\n            mute_unhandledrejection(controller.streamReader.closed);\n        }\n        if (!controller.currentStreamReaderChunk || controller.currentBufferOffset === undefined) {\n            controller.currentStreamReaderChunk = await controller.streamReader.read();\n            controller.currentBufferOffset = 0;\n        }\n        if (controller.currentStreamReaderChunk.done) {\n            if (controller.isAborted) {\n                throw new Error(\"OperationCanceledException\");\n            }\n            return 0;\n        }\n\n        const remaining_source = controller.currentStreamReaderChunk.value.byteLength - controller.currentBufferOffset;\n        mono_assert(remaining_source > 0, \"expected remaining_source to be greater than 0\");\n\n        const bytes_copied = Math.min(remaining_source, view.byteLength);\n        const source_view = controller.currentStreamReaderChunk.value.subarray(controller.currentBufferOffset, controller.currentBufferOffset + bytes_copied);\n        view.set(source_view, 0);\n        controller.currentBufferOffset += bytes_copied;\n        if (remaining_source == bytes_copied) {\n            controller.currentStreamReaderChunk = undefined;\n        }\n\n        return bytes_copied;\n    });\n}","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/dotnet/runtime/blob/b7130aa5e416e88ac48fafe92bf56a9d64e13c97/src/mono/browser/runtime/http.ts#L242-L278","documentation":"Thrown by http_wasm_get_streamed_response_bytes when the response stream reader reports done (chunk.done) while controller.isAborted is true. It surfaces as OperationCanceledException to the managed caller, signaling the response read was terminated because the request was cancelled via http_wasm_abort.","triggerScenarios":"Reading the streamed response body after the AbortController was triggered (http_wasm_abort set isAborted), so when the reader's final 'done' chunk arrives the runtime raises cancellation instead of returning 0 bytes.","commonSituations":"A CancellationToken cancels an HttpClient streaming read; the user navigates away or aborts a long-running download; explicit client-side abort of a streaming response.","solutions":["Catch OperationCanceledException (or TaskCanceledException) in managed code and treat it as normal cancellation, not a fault.","Ensure cancellation tokens are only triggered when you actually intend to cancel, to avoid spurious exceptions during reads.","If you need a clean end-of-stream, avoid aborting; let the reader finish naturally."],"exampleFix":"// before: abort surfaces as an unhandled exception\n//   var bytes = await response.Content.ReadAsByteArrayAsync();\n// after: handle cancellation explicitly\ntry { var bytes = await response.Content.ReadAsByteArrayAsync(ct); }\ncatch (OperationCanceledException) when (ct.IsCancellationRequested) { /* expected */ }","handlingStrategy":"try-catch","validationCode":"// Check the cancellation token before/while reading the streamed response\nif (ct.IsCancellationRequested) return; // don't read after cancel","typeGuard":null,"tryCatchPattern":"try { await response.Content.ReadAsByteArrayAsync(ct); }\ncatch (OperationCanceledException) when (ct.IsCancellationRequested) { /* expected cancellation */ }","preventionTips":["Always catch OperationCanceledException for HTTP calls that carry a CancellationToken.","Only cancel when you genuinely intend to abort; don't reuse tokens across unrelated work.","Let the reader finish naturally if you want a clean end-of-stream."],"tags":["http","streaming","response","cancellation"],"analyzedSha":"b7130aa5e416e88ac48fafe92bf56a9d64e13c97","analyzedAt":"2026-08-07T06:17:13.108Z","schemaVersion":2},"datasetVersion":"2026-08-07T15:17:06.553Z"}