From 999cba8b49093d2fc38cb8632adb8854e8414d6a Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 4 Mar 2016 14:41:57 -0800 Subject: [PATCH] Include the underlying exception when giving ERR_PeWritingFailure --- .../Portable/CSharpResources.Designer.cs | 9 ++++++ .../CSharp/Portable/CSharpResources.resx | 2 +- .../Attributes/EmitTestStrongNameProvider.cs | 10 ++++-- .../Test/Emit/Emit/CompilationEmitTests.cs | 12 +++---- .../Core/Portable/Compilation/Compilation.cs | 2 +- .../Portable/VBResources.Designer.vb | 9 ++++++ .../VisualBasic/Portable/VBResources.resx | 2 +- .../Attributes/EmitTestStrongNameProvider.vb | 9 ++++-- .../Test/Emit/Emit/CompilationEmitTests.vb | 8 ++--- src/Test/Utilities/Shared/Pe/BrokenStream.cs | 31 ++++++++++++++----- 10 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs index c7dbd03b04b..155950099ab 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -7045,6 +7045,15 @@ internal class CSharpResources { } } + /// + /// Looks up a localized string similar to An error occurred while writing the output file: {0}. + /// + internal static string ERR_PeWritingFailure { + get { + return ResourceManager.GetString("ERR_PeWritingFailure", resourceCulture); + } + } + /// /// Looks up a localized string similar to Neither 'is' nor 'as' is valid on pointer types. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 74de8bc06e2..11658c6f3e5 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -4676,6 +4676,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Combined length of user strings used by the program exceeds allowed limit. Try to decrease use of string literals. - An error occurred while writing the output file. + An error occurred while writing the output file: {0} diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/EmitTestStrongNameProvider.cs b/src/Compilers/CSharp/Test/Emit/Attributes/EmitTestStrongNameProvider.cs index 24e6fa4fb79..64c2df914c6 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/EmitTestStrongNameProvider.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/EmitTestStrongNameProvider.cs @@ -16,6 +16,9 @@ public partial class InternalsVisibleToAndStrongNameTests : CSharpTestBase private class StrongNameProviderWithBadInputStream : StrongNameProvider { private StrongNameProvider _underlyingProvider; + + public Exception ThrownException; + public StrongNameProviderWithBadInputStream(StrongNameProvider underlyingProvider) { _underlyingProvider = underlyingProvider; @@ -27,7 +30,8 @@ public StrongNameProviderWithBadInputStream(StrongNameProvider underlyingProvide internal override Stream CreateInputStream() { - throw new IOException("This is a test IOException"); + ThrownException = new IOException("This is a test IOException"); + throw ThrownException; } internal override StrongNameKeys CreateKeys(string keyFilePath, string keyContainerName, CommonMessageProvider messageProvider) => @@ -53,9 +57,9 @@ class C var comp = CreateCompilationWithMscorlib(src, options: options); - comp.VerifyEmitDiagnostics( + comp.Emit(new MemoryStream()).Diagnostics.Verify( // error CS8104: An error occurred while writing the Portable Executable file. - Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments("This is a test IOException").WithLocation(1, 1)); + Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(testProvider.ThrownException.ToString()).WithLocation(1, 1)); } } } diff --git a/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs index 2f17b18265e..4b6d6ca83bd 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs @@ -2701,13 +2701,13 @@ public void BrokenOutStream() var result = compilation.Emit(output); result.Diagnostics.Verify( // error CS8104: An error occurred while writing the Portable Executable file. - Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments("I/O error occurred.").WithLocation(1, 1)); + Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(output.ThrownException.ToString()).WithLocation(1, 1)); - output.BreakHow = 1; + output.BreakHow = BrokenStream.BreakHowType.ThrowOnSetPosition; result = compilation.Emit(output); result.Diagnostics.Verify( // error CS8104: An error occurred while writing the Portable Executable file. - Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments("Specified method is not supported.").WithLocation(1, 1)); + Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(output.ThrownException.ToString()).WithLocation(1, 1)); // disposed stream is not writable var outReal = new MemoryStream(); @@ -2723,7 +2723,7 @@ public void BrokenPDBStream() var output = new MemoryStream(); var pdb = new BrokenStream(); - pdb.BreakHow = 2; + pdb.BreakHow = BrokenStream.BreakHowType.ThrowOnSetLength; var result = compilation.Emit(output, pdb); // error CS0041: Unexpected error writing debug information -- 'Exception from HRESULT: 0x806D0004' @@ -2969,12 +2969,12 @@ public static void Main() }"; var compilation = CreateCompilationWithMscorlib(source); var broken = new BrokenStream(); - broken.BreakHow = 0; + broken.BreakHow = BrokenStream.BreakHowType.ThrowOnWrite; var result = compilation.Emit(broken); Assert.False(result.Success); result.Diagnostics.Verify( // error CS8104: An error occurred while writing the Portable Executable file. - Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments("I/O error occurred.").WithLocation(1, 1)); + Diagnostic(ErrorCode.ERR_PeWritingFailure).WithArguments(broken.ThrownException.ToString()).WithLocation(1, 1)); } } } diff --git a/src/Compilers/Core/Portable/Compilation/Compilation.cs b/src/Compilers/Core/Portable/Compilation/Compilation.cs index 18796e9b251..9fdbdef715c 100644 --- a/src/Compilers/Core/Portable/Compilation/Compilation.cs +++ b/src/Compilers/Core/Portable/Compilation/Compilation.cs @@ -1908,7 +1908,7 @@ private static EmitResult ToEmitResultAndFree(DiagnosticBag diagnostics, bool su } catch (Cci.PeWritingException e) { - diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_PeWritingFailure, Location.None, e.Message)); + diagnostics.Add(MessageProvider.CreateDiagnostic(MessageProvider.ERR_PeWritingFailure, Location.None, e.InnerException.ToString())); return false; } catch (ResourceException e) diff --git a/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb b/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb index 05d122330a6..c28b8679521 100644 --- a/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb +++ b/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb @@ -9009,6 +9009,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End Get End Property + ''' + ''' Looks up a localized string similar to An error occurred while writing the output file: {0}. + ''' + Friend ReadOnly Property ERR_PeWritingFailure() As String + Get + Return ResourceManager.GetString("ERR_PeWritingFailure", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to Cannot embed interop types from assembly '{0}' because it is missing the '{1}' attribute.. ''' diff --git a/src/Compilers/VisualBasic/Portable/VBResources.resx b/src/Compilers/VisualBasic/Portable/VBResources.resx index 7d49b24dd86..61fc5be02d7 100644 --- a/src/Compilers/VisualBasic/Portable/VBResources.resx +++ b/src/Compilers/VisualBasic/Portable/VBResources.resx @@ -5348,6 +5348,6 @@ Combined length of user strings used by the program exceeds allowed limit. Try to decrease use of string or XML literals. - An error occurred while writing the output file. + An error occurred while writing the output file: {0} diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/EmitTestStrongNameProvider.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/EmitTestStrongNameProvider.vb index f79884e8ffb..3aa0d8c1ed0 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/EmitTestStrongNameProvider.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/EmitTestStrongNameProvider.vb @@ -11,6 +11,8 @@ Partial Public Class InternalsVisibleToAndStrongNameTests Private Class StrongNameProviderWithBadInputStream Inherits StrongNameProvider Private _underlyingProvider As StrongNameProvider + Public Property ThrownException As Exception + Public Sub New(underlyingProvider As StrongNameProvider) _underlyingProvider = underlyingProvider End Sub @@ -25,7 +27,8 @@ Partial Public Class InternalsVisibleToAndStrongNameTests End Function Friend Overrides Function CreateInputStream() As Stream - Throw New IOException("This is a test IOException") + ThrownException = New IOException("This is a test IOException") + Throw ThrownException End Function Friend Overrides Function CreateKeys(keyFilePath As String, keyContainerName As String, messageProvider As CommonMessageProvider) As StrongNameKeys @@ -53,8 +56,8 @@ End Class , options:=options) - comp.VerifyEmitDiagnostics( - Diagnostic(ERRID.ERR_PeWritingFailure).WithArguments("This is a test IOException").WithLocation(1, 1)) + comp.Emit(New MemoryStream()).Diagnostics.Verify( + Diagnostic(ERRID.ERR_PeWritingFailure).WithArguments(testProvider.ThrownException.ToString()).WithLocation(1, 1)) End Sub diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/CompilationEmitTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/CompilationEmitTests.vb index f743f944c13..cf68dca8fda 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/CompilationEmitTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/CompilationEmitTests.vb @@ -2939,14 +2939,14 @@ End Module Dim emitResult As EmitResult Using output = New BrokenStream() - output.BreakHow = 0 + output.BreakHow = BrokenStream.BreakHowType.ThrowOnWrite emitResult = compilation.Emit(output, Nothing, Nothing, Nothing) - End Using - CompilationUtils.AssertTheseDiagnostics(emitResult.Diagnostics, + CompilationUtils.AssertTheseDiagnostics(emitResult.Diagnostics, -BC37256: An error occurred while writing the output file. +BC37256: An error occurred while writing the output file: <%= output.ThrownException.ToString() %> ) + End Using End Sub End Class End Namespace diff --git a/src/Test/Utilities/Shared/Pe/BrokenStream.cs b/src/Test/Utilities/Shared/Pe/BrokenStream.cs index 24c000eff7f..7eb5c77c120 100644 --- a/src/Test/Utilities/Shared/Pe/BrokenStream.cs +++ b/src/Test/Utilities/Shared/Pe/BrokenStream.cs @@ -7,7 +7,15 @@ namespace Roslyn.Test.Utilities { internal class BrokenStream : Stream { - public int BreakHow; + public enum BreakHowType + { + ThrowOnSetPosition, + ThrowOnWrite, + ThrowOnSetLength + } + + public BreakHowType BreakHow; + public Exception ThrownException { get; private set; } public override bool CanRead { @@ -44,8 +52,11 @@ public override long Position } set { - if (BreakHow == 1) - throw new NotSupportedException(); + if (BreakHow == BreakHowType.ThrowOnSetPosition) + { + ThrownException = new NotSupportedException(); + throw ThrownException; + } } } @@ -61,14 +72,20 @@ public override long Seek(long offset, SeekOrigin origin) public override void SetLength(long value) { - if (BreakHow == 2) - throw new IOException(); + if (BreakHow == BreakHowType.ThrowOnSetLength) + { + ThrownException = new IOException(); + throw ThrownException; + } } public override void Write(byte[] buffer, int offset, int count) { - if (BreakHow == 0) - throw new IOException(); + if (BreakHow == BreakHowType.ThrowOnWrite) + { + ThrownException = new IOException(); + throw ThrownException; + } } } } -- GitLab