Table of Contents

Trellis Analyzers

The Trellis analyzers help you write safer, more functional code by detecting common mistakes and suggesting best practices for Railway Oriented Programming.

Installation

dotnet add package Trellis.Analyzers

The analyzer package is automatically included when you install any Trellis package.

Analyzer Rules

Error Handling (TRLS001-TRLS006)

ID Title Severity Has Code Fix
TRLS001 Result return value is not handled Warning
TRLS002 Use Bind instead of Map when lambda returns Result Info
TRLS003 Unsafe access to Result.Value Warning
TRLS004 Unsafe access to Result.Error Warning
TRLS005 Consider using MatchError for error type discrimination Info
TRLS006 Unsafe access to Maybe.Value Warning

Value Objects (TRLS007)

ID Title Severity Has Code Fix
TRLS007 Use Create instead of TryCreate().Value Warning

Type Safety (TRLS008-TRLS011)

ID Title Severity Has Code Fix
TRLS008 Result is double-wrapped Warning
TRLS009 Incorrect async Result usage (blocking) Warning
TRLS010 Use specific error type instead of base Error class Info
TRLS011 Maybe is double-wrapped Warning

Code Quality (TRLS012-TRLS018)

ID Title Severity Has Code Fix
TRLS012 Consider using Result.Combine Info
TRLS013 Consider using GetValueOrDefault or Match Info
TRLS014 Use async method variant for async lambda Warning
TRLS015 Don't throw exceptions in Result chains Warning
TRLS016 Error message should not be empty Warning
TRLS017 Don't compare Result or Maybe to null Warning
TRLS018 Unsafe access to Value in LINQ expression Warning
TRLS019 Combine chain exceeds maximum supported tuple size Error

Severity Levels

  • Error: Code that will not work correctly and must be fixed
  • Warning: Potential runtime errors or correctness issues that should be fixed
  • Info: Suggestions for more idiomatic or maintainable code

Code Fixes

Several analyzers provide automatic code fixes (✅ in the table above):

  • TRLS002: Automatically replaces Map with Bind
  • TRLS003: Wraps unsafe result.Value access in if (result.IsSuccess) guard
  • TRLS004: Wraps unsafe result.Error access in if (result.IsFailure) guard
  • TRLS006: Wraps unsafe maybe.Value access in if (maybe.HasValue) guard
  • TRLS007: Replaces TryCreate().Value with Create()
  • TRLS013: Replaces ternary with GetValueOrDefault() or Match()
  • TRLS014: Replaces sync method with async variant (e.g., MapMapAsync)

Configuration

Disabling Specific Rules

You can disable specific rules in your .editorconfig:

# Disable TRLS003 for test projects
[**Tests/**/*.cs]
dotnet_diagnostic.TRLS003.severity = none

# Change TRLS007 to suggestion only
dotnet_diagnostic.TRLS007.severity = suggestion

Suppressing Warnings

Use #pragma directives for local suppression:

#pragma warning disable TRLS003
var customer = result.Value; // Intentionally unsafe in test
#pragma warning restore TRLS003

Or use [SuppressMessage] attribute:

[SuppressMessage("Trellis", "TRLS003:Unsafe access to Result.Value",
    Justification = "Test code - validating success scenario")]
public void TestMethod()
{
    var customer = result.Value;
}

Common Patterns

API Controller Pattern

[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> CreateCustomer(CreateCustomerDto dto)
    {
        return await Result.Combine(
                EmailAddress.TryCreate(dto.Email),
                Name.TryCreate(dto.Name))
            .BindAsync((email, name) => 
                customerService.CreateAsync(email, name))
            .MapAsync(customer => customer.ToDto())
            .MatchAsync(
                onSuccess: dto => Ok(dto),
                onFailure: error => error.ToHttpResult());
    }
}

This pattern avoids all analyzer warnings!

Feedback

Found a false positive or have suggestions? Open an issue on GitHub.