Skip to content

Error Handling

Ahmad Al-freihat edited this page Jan 1, 2026 · 1 revision

Error Handling

NonEmptyList<T> maintains its non-empty invariant by throwing appropriate exceptions when violations are attempted.

Creation Errors

Empty Source

Attempting to create from an empty collection throws ArgumentException:

// From empty array
NonEmptyList<int>.From(Array.Empty<int>());
// Throws: ArgumentException

// From empty list
NonEmptyList<int>.From(new List<int>());
// Throws: ArgumentException

Safe Alternative: Use TryFrom to handle potentially empty sources:

if (NonEmptyList<int>.TryFrom(source, out NonEmptyList<int>? result))
{
    // Use result
}
else
{
    // Handle empty case
}

Modification Errors

Clear

Calling Clear() throws NotSupportedException:

NonEmptyList<int> list = new(1, 2, 3);
list.Clear();
// Throws: NotSupportedException

Removing Last Element

Attempting to remove the last element throws InvalidOperationException:

NonEmptyList<int> single = new(1);
single.Remove(1);
// Throws: InvalidOperationException

single.RemoveAt(0);
// Throws: InvalidOperationException

RemoveRange

RemoveRange throws if it would empty the list:

NonEmptyList<int> list = new(1, 2, 3);
list.RemoveRange(0, 3); // Remove all
// Throws: InvalidOperationException

Null Values

For reference types, adding null throws ArgumentNullException:

NonEmptyList<string> strings = new("a", "b");
strings.Add(null!);
// Throws: ArgumentNullException

Exception Summary

Operation Exception Condition
From(empty) ArgumentException Source is empty
new(null) ArgumentNullException Null element (reference types)
Clear() NotSupportedException Always
Remove(last) InvalidOperationException Would empty the list
RemoveAt(last) InvalidOperationException Would empty the list
RemoveRange(all) InvalidOperationException Would empty the list
Add(null) ArgumentNullException Null element (reference types)
Validate(fail) ArgumentException Validation predicate fails

Best Practices

  1. Use TryFrom for unknown sources:

    if (NonEmptyList<T>.TryFrom(source, out var result))
    {
        // Safe to use result
    }
  2. Check before remove operations:

    if (list.Count > 1)
    {
        list.RemoveAt(0);
    }
  3. Use TryValidate for user input:

    if (!list.TryValidate(predicate, out var failing))
    {
        // Handle validation failure
    }

Next Steps

Clone this wiki locally