Skip to content

Commit d19a8d8

Browse files
authored
Merge pull request #21846 from unoplatform/dev/dr/invalidXamlGen3
Doc XAML gen error handling
2 parents 68dbc8f + 8afc9db commit d19a8d8

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed

src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.Errors.cs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,36 @@
77

88
namespace Uno.UI.SourceGenerators.XamlGenerator;
99

10+
/*
11+
* About error handling in XamlFileGenerator:
12+
*
13+
* *** We should raise/generate only XamlGenerationException from code generation logic. ***
14+
*
15+
* This allows to properly capture location information and context about the error and proper reporting to the user.
16+
* Other kind of exception should strictly be reserved to internal logic errors that should never happen during normal operation (including with invalid XAML file).
17+
*
18+
* Messages:
19+
* ** Error messages are reported to the end-user. **
20+
* - They must not explain internal implementation details (e.g. Value of member is null),
21+
* but rather focus on what the user did wrong and how to fix it (e.g. The 'TargetType' is not set on 'Style').
22+
* (Reminder: errors are reported with location in the XAML file, prefer simple error message avoiding fullname/namespace of types for instance).
23+
* - Variables are expected to be surrounded by simple quotes (e.g. 'MyElement') to improve readability (_follows MS logic_).
24+
* - They must not end with a dot ('.'), as the dot is added when generating the error comment in the generated code (_follows MS logic_).
25+
*
26+
* When it's possible to continue to generate valid C# code, prefer to use AddError(), GenerateError() instead of throwing.
27+
* This allows the user to get all errors of a XAML file in a single build instead of fixing them one by one.
28+
*
29+
* The Safely methods allow to properly handle errors in code generation blocks.
30+
* They should be used to wrap any code generation block that can raise exceptions.
31+
* Like for the AddError and GenerateError, they give the ability to the user to get all errors in a single build by continuing generation of the end of the XAML file.
32+
*
33+
*/
34+
35+
1036
internal partial class XamlFileGenerator
1137
{
38+
private static readonly Regex _safeMethodNameRegex = new(@"\(\) =\> (?<method>\w+)");
39+
1240
/// <summary>
1341
/// List of all errors encountered during generation.
1442
/// </summary>
@@ -41,17 +69,13 @@ private void Safely(Action<IIndentedStringBuilder> buildAction, IIndentedStringB
4169
}
4270
}
4371

44-
private static readonly Regex _safeMethodNameRegex = new(@"\(\) =\> (?<method>\w+)");
45-
4672
/// <summary>
4773
/// Invokes a build block safely, capturing any exceptions as generation errors.
4874
/// </summary>
75+
/// <remarks>The <paramref name="action"/> is expected to be a single method call. Avoid bodied delegates!</remarks>
4976
private void Safely(Action action, [CallerArgumentExpression(nameof(action))] string name = "", [CallerLineNumber] int line = -1)
5077
{
5178
Debug.Assert(_safeMethodNameRegex.IsMatch(name));
52-
var method = _safeMethodNameRegex.Match(name) is { Success: true } match
53-
? match.Groups["method"].Value
54-
: nameof(XamlFileGenerator);
5579

5680
try
5781
{
@@ -63,6 +87,10 @@ private void Safely(Action action, [CallerArgumentExpression(nameof(action))] st
6387
}
6488
catch (Exception error) when (error is not OperationCanceledException)
6589
{
90+
var method = _safeMethodNameRegex.Match(name) is { Success: true } match
91+
? match.Groups["method"].Value
92+
: nameof(XamlFileGenerator);
93+
6694
_errors.Add(new XamlGenerationException($"Processing failed for an unknown reason ({method}@{line})", error, _fileDefinition));
6795
}
6896
}

0 commit comments

Comments
 (0)