Як задокументувати викинуті винятки в c # /. Net


139

Наразі я пишу невеликий фреймворк, який буде використовуватися внутрішньо іншими розробниками в компанії.

Я хочу надати хорошу інформацію Intellisense, але я не впевнений, як документувати викинуті винятки.

У наступному прикладі:

public void MyMethod1()
{
    MyMethod2();

    // also may throw InvalidOperationException
}

public void MyMethod2()
{
    System.IO.File.Open(somepath...); // this may throw FileNotFoundException

    // also may throw DivideByZeroException
}

Я знаю, що розмітка для документування винятків:

/// <exception cref="SomeException">when things go wrong.</exception>

Що я не розумію - це документувати винятки, викинуті кодом, викликаним MyMethod1() ?

  • Чи слід документувати винятки, кинуті користувачем MyMethod2()
  • Чи слід документувати винятки, кинуті File.Open()?

Який був би найкращий спосіб документувати можливі винятки?


4
Я знаю, що це не зовсім те, про що ви задавались (і це справді давнє запитання), але Ерік Ліпперт (головний розробник компілятора для мікрософт C # та дизайнерські команди) написав повідомлення в блозі про 4 типи винятків, які, на мою думку, кожен розробник слід задуматися над тим, як писати код оброблення виключень: blogs.msdn.com/b/ericlippert/archive/2008/09/10/…
javajavajaваяваява

@javajavajavajaвава Дякую за посилання - безумовно, варто прочитати.
Арнольд Зокас

Я думаю, що це правильне питання, оскільки зовсім не очевидно, як правильно документувати винятки в C #, а перегляд 50K показує, що це також не очевидно для багатьох людей. Друга найбільш проголосована відповідь є дуже корисною, оскільки показує використання існуючих xmldocs для документування цього. Голосування за повторне відкриття. Ця "заснована на думці" близька причина вбиває безліч насправді дуже корисних питань програмування.
Олексій

Відповіді:


110

Ви повинні задокументувати всі винятки, які можуть бути викинуті вашим кодом, включаючи ті, в яких методах ви можете зателефонувати.

Якщо список стає трохи більшим, ви можете створити свій власний тип виключення. Ловіть усі, з якими ви можете зіткнутися у своєму методі, загорніть їх у виняток і киньте це.

Можливо, ви також хочете зробити це таким чином, якщо ваш метод стоїть на обличчі вашого API. Так само, як фасад спрощує декілька інтерфейсів в єдиний інтерфейс, ваш API повинен спростити декілька винятків в єдиний виняток. Полегшує використання коду для абонентів.


Щоб відповісти на деякі занепокоєння Ендрю (з коментарів), існує три типи винятків: ті, про кого ви не знаєте, ті, про яких ви знаєте, і не можуть нічого з цим робити, і ті, про яких ви знаєте і можуть щось робити.

Тих, про кого ти не знаєш, хочеш відпустити. Її головна помилка - швидше виходить з ладу ваш додаток, ніж вводити стан, у якому ви можете зіпсувати свої дані. Збіг розповість про те, що сталося та чому, що може допомогти винести цей виняток із списку "тих, про кого ви не знаєте".

Ті, про кого ви знаєте і про які нічого не можете зробити, - це винятки, такі як OutOfMemoryExceptions. У крайньому випадку ви можете обробляти такі винятки, але якщо у вас є досить чудові вимоги, ви ставитесь до них як до першої категорії - відпустіть їх. Чи є у документувати ці винятки? Ви б виглядали досить нерозумним документуванням OOM на кожен метод, який з’являється на новому об'єкті.

Ті, про кого ви знаєте і можете щось зробити, - це ті, про які слід документувати та обгортати.

Ви можете знайти ще кілька рекомендацій щодо обробки винятків тут.


3
Треба визнати, це не дуже зручно. Я не уявляю, скільки потенційних винятків може бути викинуто будь-яким кодом, який я можу зателефонувати, плюс є такі речі, як OutOfMemoryException, які ви б не хотіли ловити та обробляти.
Ендрю Заєць

3
Ваша відповідь хороша, але насправді дві відповіді суперечать одна одній. "документуйте кожен виняток, який може бути викинутий вашим кодом" та "ті, про кого ви знаєте і можете щось робити, - це ті, про які ви повинні документувати".
tymtam

2
@Tymek: Ні. Перша половина відповіла на питання "як я повинен документувати винятки", друга частина вказала на явно очевидну відповідь на те, "які винятки я повинен документувати". Перший не означає, що ви документуєте всі винятки, які, можливо, коли-небудь трапляться. Деякі люди занадто буквальні, що вимагало другого тайму.

5
@Tymek Я думаю, ваш твір може полягати в тому, що якщо ви можете щось з цим зробити, то чому б не зробити щось з цим замість того, щоб перекинути його і документувати? Можливо, буде більш правдивим сказати "Ті, про кого ви знаєте, що клієнтський код може щось зробити". Це усуває протиріччя, оскільки це ідеальні винятки для документування.
мо.

Що стосується винятків, які ви "відпускаєте", ви завжди можете їх зафіксувати на нижчому рівні, який записує їх чи щось таке. Ти знаєш; просто зробити зручним для користувача спосіб відключення програми.
Nyerguds

96

Ви повинні використовувати стандартну документацію xml .

/// <exception cref="InvalidOperationException">Why it's thrown.</exception>
/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod1()
{
    MyMethod2();
    // ... other stuff here
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod2()
{
    System.IO.File.Open(somepath...);
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
public void MyMethod3()
{
    try
    {
        MyMethod2();
    }
    catch (DivideByZeroException ex)
    {
        Trace.Warning("We tried to divide by zero, but we can continue.");
    }
}

Цінність цього способу полягає в тому, що ви надаєте документацію про відомі винятки, які можуть статися. Ця документація доступна в intellisense, якщо ви використовуєте візуальну студію і можете нагадати вам (або іншим) пізніше про винятки, які ви можете очікувати.

Ви хочете вказати конкретні типи винятків, тому що ви, можливо, зможете обробити один тип винятку, тоді як інші типи є наслідком серйозної проблеми і їх неможливо виправити.


1
Як це додати якусь цінність? Наприклад, усі ці винятки - це похідні типу винятку. З мого досвіду, це не буде практично думати про будь-який інший тип виключення, який може бути викинутий з інших API, які викликаються у ваших методах. Моя думка, ми не повинні турбуватися про будь-які винятки, викинуті з методу, ніж ті, що несуть будь-яку ділову інформацію.
Ілюмінати

7
@ShiranGinige ваш досвід неправильний.
Grozz

35

Ви можете спростити процес документації за допомогою декількох чудових доповнень. Один з них - GhostDoc , безкоштовна надбудова для Visual Studio, яка створює коментарі XML-doc. Крім того, якщо ви використовуєте ReSharper , погляньте на відмінний плагін Agent Johnson для ReSharper, який додає можливість генерувати XML-коментарі для викинутих винятків.

Оновлення: Схоже, що Аген Джонсон недоступний для R # 8, замовлення Не виключно для ReSharper як альтернативи ...

Крок 1: GhostDoc генерує коментар XML (Ctrl-Shift-D), а плагін агента Джонсона для ReSharper пропонує також документувати виняток:

крок 1

Крок 2. Використовуйте клавішу швидкого доступу ReSharper (Alt-Enter), щоб додати документацію про виключення:

крок 2 http://i41.tinypic.com/osdhm

Сподіваюся, що це допомагає :)


Тиніпні ланки розірвані.
ANeves

11

Як я розумію, намір використовувати елемент <exception> - це використовувати його при декоруванні методів, а не винятків:

/// <summary>Does something!</summary>
/// <exception cref="DidNothingException">Thrown if nothing is actually done.</exception>
public void DoSomething()
{
// There be logic here
}

Винятки, які можуть бути викинуті за допомогою інших методів, які називаються, повинні бути вилучені, оброблені та задокументовані цими методами. Винятки, які, можливо, можуть бути кинуті .NET, або винятки, які явно викинуті вашим власним кодом, повинні бути задокументовані.

Що стосується отримання більш конкретного, ніж цього, можливо, ви можете зловити і викинути свої власні винятки?


4

Частиною договору для вашого методу має бути перевірка правильності попередніх умов, тому:

public void MyMethod2()
{
    System.IO.File.Open(somepath...); // this may throw FileNotFoundException
}

стає

/// <exception cref="FileNotFoundException">Thrown when somepath isn't a real file.</exception>
public void MyMethod2()
{
    FileInfo fi = new FileInfo( somepath );
    if( !fi.Exists )
    {
        throw new FileNotFoundException("somepath doesn't exists")
    }
    // Maybe go on to check you have permissions to read from it.

    System.IO.File.Open(somepath...); // this may still throw FileNotFoundException though
}

При такому підході простіше задокументувати всі винятки, які ви явно кидаєте, без необхідності документувати, що OutOfMemoryException може бути кинуто тощо.


1
Не впевнений, у чому сенс цієї перевірки, якщо ви збираєтесь просто дублювати виняток, який Openвиклик все-таки буде кинутий (не кажучи вже про те, що ви зазначаєте, що там гонка, і перевірка не гарантує успіх Open). .
Метт Енрайт

1
@MattEnright Зрозуміло, але я зробив це трохи надуманим, щоб проілюструвати суть ...
Rowland Shaw

1

Ви повинні задокументувати всі винятки, які, можливо, можуть бути викинуті вашим методом.

Щоб приховати деталі реалізації, я спробував би сам обробити деякі винятки з MyMethod2.

Ви можете розглянути можливість їх відновлення, якщо ви не можете впоратися або вирішити виняток. Переважно упаковані / загорнуті в більш важливий виняток для абонента.


1

Дійсно, як уже було сказано, спосіб документувати винятки - це використання коментарів XML.

Окрім плагінів, ви також можете використовувати інструменти статичного аналізу, які можна інтегрувати з TFS, щоб переконатися, що винятки задокументовані.

У посиланнях нижче ви можете побачити, як створити спеціальне правило для StyleCop для перевірки винятків, викинутих вашими методами, документується.

http://www.josefcobonnin.com/post/2009/01/11/Xml-Documentation-Comments-Exceptions-I.aspx http://www.josefcobonnin.com/post/2009/01/15/Xml-Documentation -Коменти-винятки-II.aspx

З повагою


0

Документуйте очікувані винятки у вашому методі, у вашому прикладі я б дав користувачеві знати, що цей метод може викинути файл, не знайдений виняток.

Пам'ятайте, що потрібно повідомити абоненту, що чекати, щоб вони могли вибрати, як з цим боротися.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.