From b2dba8d9059267565d2331ad887a57e53d940ea6 Mon Sep 17 00:00:00 2001 From: Brennan Date: Tue, 27 Oct 2020 17:09:58 -0700 Subject: [PATCH] Throw when reader is completed with an exception (#43776) --- .../src/System/IO/Pipelines/Pipe.cs | 2 +- .../tests/PipeReaderWriterFacts.cs | 46 +++++++++++++++------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs index 90964cd..842abf6 100644 --- a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs +++ b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs @@ -960,7 +960,7 @@ namespace System.IO.Pipelines ThrowHelper.ThrowInvalidOperationException_NoWritingAllowed(); } - if (_readerCompletion.IsCompleted) + if (_readerCompletion.IsCompletedOrThrow()) { return new ValueTask(new FlushResult(isCanceled: false, isCompleted: true)); } diff --git a/src/libraries/System.IO.Pipelines/tests/PipeReaderWriterFacts.cs b/src/libraries/System.IO.Pipelines/tests/PipeReaderWriterFacts.cs index 61126ab..987c239 100644 --- a/src/libraries/System.IO.Pipelines/tests/PipeReaderWriterFacts.cs +++ b/src/libraries/System.IO.Pipelines/tests/PipeReaderWriterFacts.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -199,37 +200,54 @@ namespace System.IO.Pipelines.Tests Assert.Equal(" World", Encoding.ASCII.GetString(worldBytes)); } - [Fact] - public async Task ReadAsync_ThrowsIfWriterCompletedWithException() + [MethodImpl(MethodImplOptions.NoInlining)] + void ThrowTestException(Exception ex, Action catchAction) { - void ThrowTestException() + try { - try - { - throw new InvalidOperationException("Writer exception"); - } - catch (Exception e) - { - _pipe.Writer.Complete(e); - } + throw ex; + } + catch (Exception e) + { + catchAction(e); } + } - ThrowTestException(); + [Fact] + public async Task ReadAsync_ThrowsIfWriterCompletedWithException() + { + ThrowTestException(new InvalidOperationException("Writer exception"), e => _pipe.Writer.Complete(e)); InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(async () => await _pipe.Reader.ReadAsync()); Assert.Equal("Writer exception", invalidOperationException.Message); - Assert.Contains("ThrowTestException", invalidOperationException.StackTrace); + Assert.Contains(nameof(ThrowTestException), invalidOperationException.StackTrace); invalidOperationException = await Assert.ThrowsAsync(async () => await _pipe.Reader.ReadAsync()); Assert.Equal("Writer exception", invalidOperationException.Message); - Assert.Contains("ThrowTestException", invalidOperationException.StackTrace); + Assert.Contains(nameof(ThrowTestException), invalidOperationException.StackTrace); Assert.Single(Regex.Matches(invalidOperationException.StackTrace, "Pipe.GetReadResult")); } [Fact] + public async Task WriteAsync_ThrowsIfReaderCompletedWithException() + { + ThrowTestException(new InvalidOperationException("Reader exception"), e => _pipe.Reader.Complete(e)); + + InvalidOperationException invalidOperationException = + await Assert.ThrowsAsync(async () => await _pipe.Writer.WriteAsync(new byte[1])); + + Assert.Equal("Reader exception", invalidOperationException.Message); + Assert.Contains(nameof(ThrowTestException), invalidOperationException.StackTrace); + + invalidOperationException = await Assert.ThrowsAsync(async () => await _pipe.Writer.WriteAsync(new byte[1])); + Assert.Equal("Reader exception", invalidOperationException.Message); + Assert.Contains(nameof(ThrowTestException), invalidOperationException.StackTrace); + } + + [Fact] public async Task ReaderShouldNotGetUnflushedBytes() { // Write 10 and flush -- 2.7.4