【问题标题】:How to include exception details in a custom diagnostic warning?如何在自定义诊断警告中包含异常详细信息?
【发布时间】:2021-11-25 11:29:10
【问题描述】:

我有一个 C# 源代码生成器,如果在生成过程中抛出异常,我想报告一个警告。

我可以成功地发出警告,并附上描述,但是我找不到包含更多详细信息的方法,我在其他报告的警告中看到了这些详细信息。

这是我目前得到的:

[Generator]
public sealed partial class MyGenerator : ISourceGenerator
{
    private static readonly DiagnosticDescriptor UnexpectedErrorDiagnostic = new DiagnosticDescriptor(
        id: "MYCUSTOMID001",
        title: "Unexpected Error During Generation",
        messageFormat: "Error for object",
        category: "Design",
        DiagnosticSeverity.Warning, isEnabledByDefault: true);

    public void Execute(GeneratorExecutionContext context)
    {
        try
        {
            // Some logic, which might throw an exception
        }
        catch (Exception ex)
        {
            context.ReportDiagnostic(Diagnostic.Create(UnexpectedErrorDiagnostic, Location.None));
        }
    }
}

当这个问题出现时,代码和描述设置正确:

我想要做的是在同一个诊断中包含异常详细信息,以便可以扩展警告,就像我看到的其他一些警告一样:

我尝试在 Diagnostic.Create 期间设置 Properties 属性,但它们没有显示在任何地方。

如何在自定义诊断中包含这些详细信息?

【问题讨论】:

    标签: c# sourcegenerators


    【解决方案1】:

    您所看到的RS2000 有点不同。这是从诊断分析器报告的诊断规则。它使用相同的DiagnosticDescriptor 类,但它对源生成器的处理方式不同。例如,DiagnosticAnalyzer 期望派生类提供支持的诊断列表(通过SupportedDiagnostics)。

    DiagnosticAnalyzer 中的诊断报告

    这是一个诊断分析器的极简示例:

    [DiagnosticAnalyzer(LanguageNames.CSharp)]
    public class MyDiagnosticAnalyzer : DiagnosticAnalyzer
    {
        private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
            id: "MYCUSTOMID001",
            title: "Unexpected Error",
            messageFormat: "Error for object",
            category: "Design",
            defaultSeverity: DiagnosticSeverity.Warning,
            isEnabledByDefault: true,
            description: "MYCUSTOMID001 long description. This line will be shown in the error list panel");
    
        public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
    
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();
            context.RegisterSyntaxTreeAction(AnalyzeAction);
        }
    
        private static void AnalyzeAction(SyntaxTreeAnalysisContext context)
        {
            // ...
            context.ReportDiagnostic(Diagnostic.Create(Rule, Location.None));
        }
    }
    

    它报告一个警告,其中包含来自Description 实例的Description getter 的可扩展详细信息:

    SourceGenerator 中的诊断报告

    虽然它适用于诊断分析器,但它似乎不适用于源生成器。

    [Generator]
    public sealed class MySourceGenerator : ISourceGenerator
    {
        public void Initialize(GeneratorInitializationContext context)
        {
        }
    
        public void Execute(GeneratorExecutionContext context)
        {
            // ...
            var descriptor = new DiagnosticDescriptor(
                id: "MYCUSTOMID002",
                title: "Unexpected Error",
                messageFormat: "Error for object",
                category: "Design",
                defaultSeverity: DiagnosticSeverity.Warning,
                isEnabledByDefault: true,
                description: "MYCUSTOMID002 long description. This line will be shown in the error list panel");
    
            context.ReportDiagnostic(Diagnostic.Create(descriptor, Location.None));
        }
    }
    

    如我们所见,消息中没有显示Description


    解决方法(嗯,不是真的)

    您仍然可以使用MessageFormat 属性从源生成器提供有意义的诊断详细信息,并稍后将正确的格式参数传递给Diagnostic.Create

    这是一个例子:

    public void Execute(GeneratorExecutionContext context)
    {
        // ...
        var descriptor = new DiagnosticDescriptor(
            id: "MYCUSTOMID002",
            title: "Unexpected Error",
            messageFormat: "Error for object: {0}",
            category: "Design",
            defaultSeverity: DiagnosticSeverity.Warning,
            isEnabledByDefault: true);
    
        context.ReportDiagnostic(Diagnostic.Create(descriptor, Location.None, "Exception long description, stack trace, etc."));
    }
    

    它会产生这个消息:

    但我知道这不是您想要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-09
      • 2011-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-25
      相关资源
      最近更新 更多