Skip to content

DEVKIT1021

PhuocLe edited this page Jun 20, 2026 · 2 revisions

Use ITracingService in Catch Blocks

Description

This analyzer detects catch blocks inside plugin or workflow activity code that do not call ITracingService.Trace. Exception traces are essential when diagnosing Dataverse plugin and workflow failures, especially in sandboxed environments.

Microsoft Best Practice

📚 Use ITracingService in Plug-ins

Why This Matters

Catch blocks without tracing can cause:

  1. Lost exception details: The original stack trace or contextual data may not be visible
  2. Slow debugging: Failures require reproduction instead of reading trace logs
  3. Poor supportability: Production issues are harder to diagnose
  4. Generic user errors: Users may only see a simplified platform message

Detection

The analyzer flags catch blocks that:

  • Are inside a plugin or workflow activity class
  • Do not contain an invocation of Trace(...) on an expression typed as Microsoft.Xrm.Sdk.ITracingService

Code Examples

❌ Bad Code

public class AccountPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        try
        {
            DoWork();
        }
        catch (Exception ex)
        {
            // ❌ No trace is written before throwing
            throw new InvalidPluginExecutionException("Account processing failed.", ex);
        }
    }
}

✅ Good Code

public class AccountPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var tracingService = (ITracingService)serviceProvider
            .GetService(typeof(ITracingService));

        try
        {
            DoWork();
        }
        catch (Exception ex)
        {
            // ✅ Exception details are captured in plugin trace logs
            tracingService.Trace($"Account processing failed: {ex.Message}");
            tracingService.Trace(ex.ToString());

            throw new InvalidPluginExecutionException("Account processing failed.", ex);
        }
    }
}

How to Fix

  1. Get ITracingService from the service provider
  2. Call tracingService.Trace(...) inside each catch block
  3. Include enough context to diagnose the failing operation
  4. Re-throw with InvalidPluginExecutionException when the error should be shown through Dataverse

Before and After

  catch (Exception ex)
  {
+     tracingService.Trace(ex.ToString());
      throw new InvalidPluginExecutionException("Operation failed.", ex);
  }

Viewing Trace Logs

Trace output is captured by Dataverse when plug-in trace logging is enabled:

  1. Open Plug-in Trace Log
  2. Filter by plugin assembly, type, message, or correlation id
  3. Review the MessageBlock field for trace output

Suppression

Suppress only when a catch block intentionally handles an exception without producing Dataverse trace output.

#pragma warning disable DEVKIT1021
catch (ExpectedException)
{
    // Intentionally ignored
}
#pragma warning restore DEVKIT1021

Or in .editorconfig:

[*.cs]
dotnet_diagnostic.DEVKIT1021.severity = none

Related Rules

  • DEVKIT1011 - Use InvalidPluginExecutionException in plug-ins and workflow activities
  • DEVKIT1012 - Consider using ITracingService in plug-ins
  • DEVKIT1017 - Avoid Console output in plug-ins

Rule Properties

Property Value
Rule ID DEVKIT1021
Category DynamicsCrm.DevKit
Severity Warning
Enabled by default Yes

Clone this wiki locally