Skip to content

Roslyn Analyzers Reference ​

ALPHA

The analyzer package is currently in alpha. Rule behavior and IDs may change between releases.

This page documents the currently implemented Roslyn analyzer rules in NickSoftware.Switchboard.Analyzers.

Table of Contents ​

Installation ​

Install the analyzer package into the project(s) where you write flows:

bash
dotnet add package NickSoftware.Switchboard.Analyzers

The analyzers are intentionally shipped as a separate NuGet package.

Configuration ​

Use .editorconfig to tune severity:

ini
[*.cs]

dotnet_diagnostic.SWB002.severity = error
dotnet_diagnostic.SWB011.severity = warning
dotnet_diagnostic.SWB017.severity = none

Rule Reference ​

SWB001: Flow Must Have At Least One Action ​

  • Severity: Error
  • Category: Switchboard.Design
csharp
var flow = new FlowBuilder()
    .SetName("EmptyFlow")
    .Build(); // ❌ SWB001

SWB002: Flow Should End With Terminal Action ​

  • Severity: Warning
  • Category: Switchboard.Design
csharp
var flow = Flow.Create("IncompleteFlow")
    .PlayPrompt("Welcome")
    .Build(); // ⚠️ SWB002
csharp
var flow = Flow.Create("CompleteFlow")
    .PlayPrompt("Welcome")
    .Disconnect()
    .Build();

Code fix: Quick Action can insert .Disconnect() before .Build().


SWB004: Flow Name Must Be Set ​

  • Severity: Error
  • Category: Switchboard.Design
csharp
var flow = new FlowBuilder()
    .PlayPrompt("Welcome")
    .Disconnect()
    .Build(); // ❌ SWB004

SWB005: Queue Name Cannot Be Empty ​

  • Severity: Error
  • Category: Switchboard.Usage
csharp
var flow = Flow.Create("BadQueue")
    .PlayPrompt("Transferring...")
    .TransferToQueue("") // ❌ SWB005
    .Build();

SWB006: Prompt Text Is Required ​

  • Severity: Error
  • Category: Switchboard.Usage
csharp
var flow = Flow.Create("BadPrompt")
    .PlayPrompt(null) // ❌ SWB006
    .Disconnect()
    .Build();

SWB011: Loop Configure Lambda Invalid ​

  • Severity: Error
  • Category: Switchboard.Usage
  • Meaning: Loop(..., loop => ...) must define what happens each iteration via loop.WhileLooping(...).

Invalid (semantic bug): calling normal flow actions directly on loop:

csharp
Flow.Create("Loop Misuse")
    .Loop(3, loop =>
    {
        loop.PlayPrompt("Retrying..."); // ❌ SWB011
    })
    .Disconnect()
    .Build();

Valid:

csharp
Flow.Create("Loop Correct")
    .Loop(3, loop => loop
        .WhileLooping(body => body.PlayPrompt("Retrying..."))
        .WhenDone(done => done.Disconnect()))
    .Build();

SWB012: Wait Configure Lambda Invalid ​

  • Severity: Error
  • Category: Switchboard.Usage
  • Meaning: Wait(..., wait => ...) may only call Wait-scoped methods directly on wait.
csharp
Flow.Create("Wait Misuse")
    .Wait(10, wait =>
    {
        wait.PlayPrompt("..."); // ❌ SWB012
    })
    .Disconnect()
    .Build();

SWB013: DistributeByPercentage Configure Lambda Invalid ​

  • Severity: Error
  • Category: Switchboard.Usage
  • Meaning: DistributeByPercentage(dist => ...) must define at least one routing branch via dist.WithPercentage(...) and/or dist.Otherwise(...).
csharp
Flow.Create("Dist Missing Branches")
    .DistributeByPercentage(dist => { }) // ❌ SWB013
    .Disconnect()
    .Build();

SWB028: GetCustomerInput Branches Lambda Invalid ​

  • Severity: Error
  • Category: Switchboard.Usage
  • Meaning: GetCustomerInput(promptText, branches: input => ..., ...) must:
    • configure the required branches: OnTimeout(...), OnDefault(...), and OnError(...) (or OnInvalidInput(...))
    • not call normal flow actions directly on the input parameter (those calls usually belong inside a branch like OnDigit(...))

Invalid (semantic bug): calling a normal action directly on input:

csharp
Flow.Create("Bad Menu")
    .GetCustomerInput(
        promptText: "Press 1",
        branches: input => input.PlayPrompt("Hello"), // ❌ SWB028
        configure: _ => { },
        identifier: "menu")
    .Disconnect()
    .Build();

Invalid: missing required fallback branches:

csharp
Flow.Create("Missing Fallbacks")
    .GetCustomerInput(
        promptText: "Press 1",
        branches: input => input
            .OnDigit("1", one => one.Disconnect()),
        configure: _ => { },
        identifier: "menu") // ❌ SWB028 (missing OnTimeout/OnDefault/OnError)
    .Build();

Valid: configure required branches (and digits/intents as needed):

csharp
Flow.Create("Good Menu")
    .GetCustomerInput(
        promptText: "Press 1",
        branches: input => input
            .OnDigit("1", one => one.ThenContinue())
            .OnDefault(d => d.Disconnect())
            .OnTimeout(t => t.Disconnect())
            .OnError(e => e.Disconnect()),
        configure: action => action.TimeoutSeconds = 10,
        identifier: "menu")
    .TransferToQueue("General")
    .Disconnect()
    .Build();

SWB014: CheckHoursOfOperation Fluent Usage Invalid ​

  • Severity: Error
  • Category: Switchboard.Usage
  • Meaning: CheckHoursOfOperation(...) must configure OnInHours(...), OnOutOfHours(...), and OnError(...) before continuing with normal flow actions.
csharp
Flow.Create("Bad Hours")
    .CheckHoursOfOperation("BusinessHours")
    .PlayPrompt("We are open") // ❌ SWB014
    .Build();
csharp
Flow.Create("Good Hours")
    .CheckHoursOfOperation("BusinessHours")
        .OnInHours(open => open.TransferToQueue("Support"))
        .OnOutOfHours(closed => closed
            .PlayPrompt("We are currently closed")
            .Disconnect())
        .OnError(err => err.Disconnect())
    .Build();

SWB015: CheckStaffing Fluent Usage Invalid ​

  • Severity: Error
  • Category: Switchboard.Usage
  • Meaning: CheckStaffing(...), CheckStaffingForQueue(...), and CheckStaffingForAgent(...) must configure OnTrue(...), OnFalse(...), and OnError(...).

SWB016: CheckQueueStatus Fluent Usage Invalid ​

  • Severity: Error
  • Category: Switchboard.Usage
  • Meaning: CheckQueueStatus* must configure:
    • at least one condition (WhenTimeInQueue* / WhenQueueCapacity)
    • OnNoMatch(...)
    • OnError(...)

SWB017: CheckCallProgress Fluent Usage Invalid ​

  • Severity: Error
  • Category: Switchboard.Usage
  • Meaning: CheckCallProgress(...) must configure:
    • at least one outcome branch (OnCallAnswered / OnVoicemailBeep / OnVoicemailNoBeep / OnNotDetected)
    • OnError(...)

Notes / Limitations ​

  • Rules that inspect configure lambdas analyze inline lambdas only (they don’t follow helper methods).
  • Some branch-builder rules require configuration to be completed within a single fluent expression.

Preview release - Licensing terms TBD before 1.0