Skip to content

Commit 4e5dc41

Browse files
authored
Improving MSBuild error reporting (#269)
1 parent 69ca97e commit 4e5dc41

File tree

4 files changed

+54
-27
lines changed

4 files changed

+54
-27
lines changed

sdk/Sdk/FunctionMetadataGenerator.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ internal class FunctionMetadataGenerator
2222
private readonly IDictionary<string, string> _extensions;
2323

2424
public FunctionMetadataGenerator()
25-
: this((l, m) => { })
25+
: this((l, m, p) => { })
2626
{
2727
_extensions = new Dictionary<string, string>();
2828
}
2929

30-
public FunctionMetadataGenerator(Action<TraceLevel, string> log)
30+
public FunctionMetadataGenerator(Action<TraceLevel, string, string> log)
3131
{
3232
_logger = new IndentableLogger(log);
3333
_extensions = new Dictionary<string, string>();
@@ -81,12 +81,12 @@ public IEnumerable<SdkFunctionMetadata> GenerateFunctionMetadata(string assembly
8181
}
8282
catch (FunctionsMetadataGenerationException ex)
8383
{
84-
_logger.LogError($"Failed to generate function metadata from {Path.GetFileName(path)}.");
84+
_logger.LogError($"Failed to generate function metadata from {Path.GetFileName(path)}: {ex.Message}", path);
8585
throw ex;
8686
}
8787
catch (Exception ex)
8888
{
89-
_logger.LogWarning($"Could not evaluate '{Path.GetFileName(path)}' for functions metadata. Exception message: {ex.ToString()}");
89+
_logger.LogWarning($"Could not evaluate '{Path.GetFileName(path)}' for functions metadata. Exception message: {ex}");
9090
}
9191
}
9292
}
@@ -130,14 +130,23 @@ private void AddFunctionMetadataIfFunction(IList<SdkFunctionMetadata> functions,
130130
if (TryCreateFunctionMetadata(method, out SdkFunctionMetadata? metadata)
131131
&& metadata != null)
132132
{
133-
var allBindings = CreateBindingMetadataAndAddExtensions(method);
133+
try
134+
{
135+
136+
var allBindings = CreateBindingMetadataAndAddExtensions(method);
137+
138+
139+
foreach (var binding in allBindings)
140+
{
141+
metadata.Bindings.Add(binding);
142+
}
134143

135-
foreach(var binding in allBindings)
144+
functions.Add(metadata);
145+
}
146+
catch (FunctionsMetadataGenerationException ex)
136147
{
137-
metadata.Bindings.Add(binding);
148+
throw new FunctionsMetadataGenerationException($"Failed to generate medata for function '{metadata.Name}' (method '{method.FullName}'): {ex.Message}");
138149
}
139-
140-
functions.Add(metadata);
141150
}
142151
}
143152

@@ -217,7 +226,7 @@ private void AddOutputBindingsFromReturnType(IList<ExpandoObject> bindingMetadat
217226
else
218227
{
219228
TypeDefinition returnDefinition = returnType.Resolve()
220-
?? throw new FunctionsMetadataGenerationException($"Couldn't find the type definition {returnType}");
229+
?? throw new FunctionsMetadataGenerationException($"Couldn't find the type definition '{returnType}' for method '{method.FullName}'");
221230

222231
bool hasOutputModel = TryAddOutputBindingsFromProperties(bindingMetadata, returnDefinition);
223232

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
using System;
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Runtime.Serialization;
26

37
namespace Microsoft.Azure.Functions.Worker.Sdk
48
{
9+
[Serializable]
510
internal class FunctionsMetadataGenerationException: Exception
611
{
12+
public FunctionsMetadataGenerationException() { }
13+
714
internal FunctionsMetadataGenerationException(string message): base(message) { }
815

916
internal FunctionsMetadataGenerationException(string message, Exception innerException) : base(message, innerException) { }
10-
17+
18+
protected FunctionsMetadataGenerationException(SerializationInfo info, StreamingContext context)
19+
: base(info, context) { }
1120
}
1221
}

sdk/Sdk/IndentableLogger.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
@@ -9,10 +9,10 @@ namespace Microsoft.Azure.Functions.Worker.Sdk
99
internal class IndentableLogger
1010
{
1111
private const int SpacesPerIndent = 2;
12-
private readonly Action<TraceLevel, string> _log;
12+
private readonly Action<TraceLevel, string, string> _log;
1313
private int _indent = 0;
1414

15-
public IndentableLogger(Action<TraceLevel, string> log)
15+
public IndentableLogger(Action<TraceLevel, string, string> log)
1616
{
1717
_log = log ?? throw new ArgumentNullException(nameof(log));
1818
}
@@ -37,17 +37,17 @@ private void PopIndent()
3737

3838
public void LogMessage(string message)
3939
{
40-
_log(TraceLevel.Info, Indent(message));
40+
_log(TraceLevel.Info, Indent(message), string.Empty);
4141
}
4242

43-
public void LogError(string message)
43+
public void LogError(string message, string? filePath = null)
4444
{
45-
_log(TraceLevel.Error, Indent(message));
45+
_log(TraceLevel.Error, Indent(message), filePath ?? string.Empty);
4646
}
4747

4848
public void LogWarning(string message)
4949
{
50-
_log(TraceLevel.Warning, Indent(message));
50+
_log(TraceLevel.Warning, Indent(message), string.Empty);
5151
}
5252

5353
private string Indent(string message)

sdk/Sdk/Tasks/GenerateFunctionMetadata.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,34 @@ public class GenerateFunctionMetadata : Task
3232

3333
public override bool Execute()
3434
{
35-
var functionGenerator = new FunctionMetadataGenerator(MSBuildLogger);
36-
var functions = functionGenerator.GenerateFunctionMetadata(AssemblyPath!, ReferencePaths.Select(p => p.ItemSpec));
35+
try
36+
{
37+
var functionGenerator = new FunctionMetadataGenerator(MSBuildLogger);
38+
39+
var functions = functionGenerator.GenerateFunctionMetadata(AssemblyPath!, ReferencePaths.Select(p => p.ItemSpec));
3740

38-
var extensions = functionGenerator.Extensions;
39-
var extensionsCsProjGenerator = new ExtensionsCsprojGenerator(extensions, ExtensionsCsProjFilePath!, ExtensionsTargetFramework!);
41+
var extensions = functionGenerator.Extensions;
42+
var extensionsCsProjGenerator = new ExtensionsCsprojGenerator(extensions, ExtensionsCsProjFilePath!, ExtensionsTargetFramework!);
4043

41-
extensionsCsProjGenerator.Generate();
44+
extensionsCsProjGenerator.Generate();
4245

43-
FunctionMetadataJsonWriter.WriteMetadata(functions, OutputPath!);
46+
FunctionMetadataJsonWriter.WriteMetadata(functions, OutputPath!);
47+
}
48+
catch (FunctionsMetadataGenerationException)
49+
{
50+
Log.LogError($"Unable to build Azure Functios metadata for {AssemblyPath}");
51+
return false;
52+
}
4453

4554
return true;
4655
}
4756

48-
private void MSBuildLogger(TraceLevel level, string message)
57+
private void MSBuildLogger(TraceLevel level, string message, string path)
4958
{
5059
switch (level)
5160
{
5261
case TraceLevel.Error:
53-
Log.LogError(message);
62+
Log.LogError(null, null, null, file: path, 0, 0, 0, 0, message: message);
5463
break;
5564
case TraceLevel.Info:
5665
Log.LogMessage(message);

0 commit comments

Comments
 (0)