Table of Contents

TRLS004: Unsafe access to Result.Error

Cause

Accessing Result.Error without first checking IsFailure or using proper guards.

Rule Description

Result.Error throws an InvalidOperationException if the Result is in a success state. Accessing it without checking IsFailure first can cause runtime exceptions.

How to Fix Violations

Option 1: Check IsFailure First

// ❌ Bad - Unsafe access
var error = result.Error;

// ✅ Good - Guarded access
if (result.IsFailure)
{
    var error = result.Error;
    Logger.LogError(error.Detail);
}

Option 2: Use Match

// ✅ Good - Pattern matching
return result.Match(
    onSuccess: customer => Ok(customer),
    onFailure: error => BadRequest(error));

Option 3: Use TryGetError

// ✅ Good - Safe extraction
if (result.TryGetError(out var error))
{
    Logger.LogError(error.Detail);
}

Code Fix

This diagnostic offers an automatic code fix that wraps the unsafe access in an if (result.IsFailure) guard.

Example Code Fix Transformation

Before:

var result = GetCustomer();
var error = result.Error;
Logger.LogError(error.Code);

After (automatic):

var result = GetCustomer();
if (result.IsFailure)
{
    var error = result.Error;
    Logger.LogError(error.Code);
}

When to Suppress Warnings

This warning can be suppressed in test code where you're explicitly testing failure scenarios.

[Fact]
public void Should_FailWithInvalidEmail()
{
    var result = Customer.Create("invalid-email");
    result.IsFailure.Should().BeTrue();
    #pragma warning disable TRLS004
    result.Error.Should().BeOfType<ValidationError>();
    #pragma warning restore TRLS004
}
  • TRLS003 - Unsafe access to Result.Value
  • TRLS005 - Consider using MatchError for error type discrimination