CommandResponse<T>: Simplifying Success and Error Handling in C#

Understanding CommandResponse<T> in C#

When building applications, it’s common to write methods that need to return data along with the status of execution (success or failure). Instead of just returning raw data or a boolean, a better approach is to use a wrapper response object.

What is CommandResponse<T>?

CommandResponse<T> is a generic wrapper class that can hold:

  • Data: the actual result of the operation.

  • Errors: a list of errors if something went wrong.

  • Success: a quick way to check if the operation succeeded.

  
    public class CommandResponse<T> where T : class, new()
{
    public T? Data { get; set; }
    public List<UserError>? Errors { get; set; }

    // Success is true if there are no errors
    public bool Success => Errors == null || Errors.Count == 0;
}

public class UserError
{
    public string Code { get; set; }
    public string Message { get; set; }
}
  

Why use it?

Imagine you are calling a service method like CreateUser. You don’t just want to know if it worked — you also want:

  • The created user details (on success).

  • The reason for failure (on error).

Instead of returning User or bool, you wrap everything into CommandResponse<User>.

Example: Service Method with CommandResponse<T>

  
    public CommandResponse<User> CreateUser(string name, string email)
{
    var response = new CommandResponse<User>();

    if (string.IsNullOrWhiteSpace(name))
    {
        response.Errors = new List<UserError>
        {
            new UserError { Code = "NAME_EMPTY", Message = "Name cannot be empty." }
        };
        return response;
    }

    if (!email.Contains("@"))
    {
        response.Errors = new List<UserError>
        {
            new UserError { Code = "INVALID_EMAIL", Message = "Email is not valid." }
        };
        return response;
    }

    // If everything is fine, create a user
    response.Data = new User { Id = 1, Name = name, Email = email };
    return response;
}
  

How to Use It

  
    var service = new UserService();
var result = service.CreateUser("Shubham", "[email protected]");

if (result.Success)
{
    Console.WriteLine($"User created: {result.Data.Name}");
}
else
{
    foreach (var error in result.Errors)
    {
        Console.WriteLine($" Error: {error.Code} - {error.Message}");
    }
}
  

Benefits of CommandResponse<T>

  1. Consistency: Every method can return success, data, and errors in a structured way.

  2. Error Handling: avoids throwing exceptions for normal validation failures.

  3. Clean Code: separates data from error handling.

 In short, CommandResponse<T> is a standardised response wrapper that makes your code cleaner, easier to test, and more maintainable.