Как я могу выбросить исключение и добавить свое собственное сообщение, содержащее ключ и значение? - PullRequest
5 голосов
/ 17 декабря 2011

У меня есть методы, которые выглядят следующим образом:

public IDictionary<string, string> Delete(Account account)
{
    try { _accountRepository.Delete(account); }
    catch { _errors.Add("", "Error when deleting account"); }
    return _errors;
}

public IDictionary<string, string> ValidateNoDuplicate(Account ac)
{
    var accounts = GetAccounts(ac.PartitionKey);
    if (accounts.Any(b => b.Title.Equals(ac.Title) &&
                            !b.RowKey.Equals(ac.RowKey)))
        _errors.Add("Account.Title", "Duplicate");
    return _errors;
}

Я хотел бы изменить этот метод так, чтобы он возвращал bool и, таким образом, он выдавал исключение, если вместо:

_errors.Add("", "Error when deleting account");

Может кто-нибудь объяснить мне, как я могу выбросить исключение и передать сообщение, содержащее ключ и значение.В этом случае ключ будет "", а значение будет "Error when deleting account".

Также в методе, который вызывает это.Как бы я поймал исключение?

Нужно ли мне создавать свой собственный класс и каким-то образом выдавать исключение на основе этого класса?

Ответы [ 4 ]

6 голосов
/ 17 декабря 2011

Класс Exception имеет свойство Data, которое представляет собой словарь пар ключ / значение.

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;
}

Обратите внимание, что, как правило, рекомендуется использовать исключения, которые можно сериализировать, поэтому объекты, помещаемые в словарь данных, также должны быть сериализуемыми. В вашем примере вы просто вводите строки, так что все будет в порядке.

Было бы необходимо, чтобы я создал свой собственный класс и каким-то образом выдал исключение на основе этого класса?

Конечно, необязательно для создания собственного пользовательского класса Exception, и это может быть нежелательно. Рекомендации по проектированию MSDN для исключений содержат рекомендации по выбору типа исключения для .

Как правило, вы предпочитаете использовать один из существующих типов исключений, если только у вас нет условия ошибки, которое может быть программно обработано иначе, чем существующие типы исключений.

6 голосов
/ 17 декабря 2011

Создайте свой собственный класс исключений, который может содержать необходимые вам данные:

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) {}

}

В ваших методах вы можете выбросить исключение.Не возвращайте также состояние ошибки, которое обрабатывается исключением.

Не выбрасывайте исключение, которое вы получаете в методе, включите его как InnerException, чтобы его можно было использовать дляотладка.

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;
  }
}

При вызове методов вы получаете тип исключения:

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
}
2 голосов
/ 17 декабря 2011

Создайте свое собственное исключение и затем бросьте его.

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");
    }
}
1 голос
/ 17 декабря 2011

Вы можете выдать свои собственные исключения вместо

_errors.Add("", "Error when deleting account");

Так что каждый _errors.Add(..) будет заменен чем-то вроде

throw new MyAppException(key, value);

Как создать собственный класс исключений было объяснено выше.Таким образом, вы предоставляете объекту исключения значение ключ и значение .

Вы должны знать, какой тип исключения вы собираетесь перехватывать

try {
  Delete(account);
} catch(NullPointerException ex) {
  throw new MyAppException(key, value);
}

И теперь в ваших методах вызова (внешних методах) вы можете перехватить только ваши исключения.

try {
  _accountRepository.Delete(account);
} catch(MyAppException ex) {
  //exception handle logic
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...