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
MapwithBind - TRLS003: Wraps unsafe
result.Valueaccess inif (result.IsSuccess)guard - TRLS004: Wraps unsafe
result.Erroraccess inif (result.IsFailure)guard - TRLS006: Wraps unsafe
maybe.Valueaccess inif (maybe.HasValue)guard - TRLS007: Replaces
TryCreate().ValuewithCreate() - TRLS013: Replaces ternary with
GetValueOrDefault()orMatch() - TRLS014: Replaces sync method with async variant (e.g.,
Map→MapAsync)
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.