How can I throw an exception and add in my own message containing a key and a value?

Create your own exception class, that can hold the data that you need:

public class AccountException : ApplicationException {

  public Dictionary<string, string> Errors { get; set; };

  public AccountException(Exception ex) : base(ex) {
    Errors = new Dictionary<string, string>();
  }

  public AccountException() : this(null) {}

}

In your methods you can throw the exception. Don't return an error status also, that is handled by the exception.

Don't throw away the exception that you get in the method, include that as InnerException, so that it can be used for debugging.

public void Delete(Account account) {
  try {
    _accountRepository.Delete(account);
  } catch(Exception ex) {
    AccountException a = new AccountException(ex);
    a.Errors.Add("", "Error when deleting account");
    throw a;
  }
}

public void ValidateNoDuplicate(Account ac) {
  var accounts = GetAccounts(ac.PartitionKey);
  if (accounts.Any(b => b.Title.Equals(ac.Title) &&
                            !b.RowKey.Equals(ac.RowKey))) {
    AccountException a = new AccountException();
    a.Errors.Add("Account.Title", "Duplicate");
    throw a;
  }
}

When calling the methods, you catch your exception type:

try {
  Delete(account);
} catch(AccountException ex) {
  // Handle the exception here.
  // The ex.Errors property contains the string pairs.
  // The ex.InnerException contains the actual exception
}

The Exception class has a Data property that is a dictionary of key/value pairs.

IDictionary<string, string> errors;
...

if (errors.Count > 0)
{
    Exception ex = ... construct exception of the appropriate type
    foreach(string key in _errors.Keys)
    {
        ex.Data.Add(key, _errors[key]);
    }
    throw ex;
}

Note that it's generally considered to be good practice to use Exceptions that are Serializable, so that the objects you put into the Data dictionary should also be serializable. In your example, you're just putting in strings, so you'll be fine.

Would it be necessary for me to make my own class and somehow throw an exception based on this class?

It's certainly not necessary to create your own custom Exception class, and may not be desirable. The MSDN design guidelines for Exceptions gives guidelines on choosing which Exception type to throw.

In general, you should prefer to use one of the existing Exception types unless you have an error condition that can be programatically handled in a different way from existing Exception types.


Create your own Exception and then throwing it.

public class RepositoryException : Exception
{
    public RepositoryException() : base()
    {
    }

    public RepositoryException(string key, string value) : base()
    {
        base.Data.Add(key, value);
    }

    public RepositoryException(string message) : base(message)
    {
    }

    public RepositoryException(string message, Exception innerException) : base(message, innerException)
    {
    }
}


public Boolean Delete(Account account)
{
    try 
    { 
        _accountRepository.Delete(account); 
        return true;
    }
    catch (Exception ex)
    { 
        throw new RepositoryException("", "Error when deleting account");            
        // throw new RepositoryException("Error when deleting account", ex);
        // OR just
        // throw new RepositoryException("Error when deleting account");
    }
}

Tags:

C#

Exception