Разбор C #, поиск методов и установка try / catch для всех методов - PullRequest
1 голос
/ 06 января 2009

Я знаю, это звучит странно, но я должен поставить блокировку try catch для каждого метода, чтобы перехватить все исключения. У нас есть тысячи методов, и мне нужно сделать это автоматически. Что вы предлагаете?

Я планирую проанализировать все файлы cs, определить методы и вставить блок try catch с приложением. Можете ли вы предложить мне любой парсер, который я могу легко использовать? или что-нибудь, что поможет мне ...

каждый метод имеет свой уникальный номер, например, 5006

public static LogEntry Authenticate(....)
        {
            LogEntry logEntry = null;
            try
            {
                ....
                return logEntry;
            }

            catch (CompanyException)
            {
                throw;
            }

            catch (Exception ex)
            {
                logEntry = new LogEntry(
                    "5006",
                    RC.GetString("5006"), EventLogEntryType.Error,
                    LogEntryCategory.Foo);

                throw new CompanyException(logEntry, ex);
            }
        }

Я создал это для этого; http://thinkoutofthenet.com/index.php/2009/01/12/batch-code-method-manipulation/

Ответы [ 18 ]

40 голосов
/ 06 января 2009

НЕ ДЕЛАЙТЕ ЭТОГО. Нет никаких веских причин для обработки ошибок pokemon ("должен поймать их всех").

РЕДАКТИРОВАТЬ: Через несколько лет небольшой пересмотр в порядке. Я бы сказал вместо этого «по крайней мере, не делайте этого вручную». Используйте инструмент AOP или ткач, например PostSharp или Fody, чтобы применить его к коду конечного результата, но обязательно учитывайте другие полезные точки трассировки или диагностические данные, такие как время захвата выполнения, входные параметры, выходные параметры и т. Д.

12 голосов
/ 06 января 2009

Ну, если вам нужно сделать это, тогда вы должны. Однако вы можете попытаться убедить любого, кто заставляет вас сделать это, позволить вам использовать событие UnhandledException класса AppDomain . Он будет уведомлять вас о каждом неперехваченном исключении в любом методе, прежде чем он будет сообщен пользователю. Поскольку вы также можете получить трассировку стека от объекта исключения, вы сможете точно определить, где происходит каждое исключение. Это гораздо лучшее решение, чем повсеместное оснащение вашего кода обработчиками исключений.

С учетом сказанного, если бы у меня было , чтобы сделать это, я бы использовал некоторые регулярные выражения для определения начала и конца каждого метода и использовал бы его для повсеместного добавления какого-либо обработчика исключений. Трюк при написании регулярного выражения для этого случая будет в определении балансировочной группы, объясненном более подробно в документации MSDN здесь . Существует также соответствующий пример использования групп балансировки здесь .

3 голосов
/ 06 января 2009

Может быть, тот, кто придумал это требование, не понимает, что вы все равно можете перехватить все исключения (сверху), не вставляя try-catch в каждую функцию. Вы можете увидеть пример того, как перехватить все необработанные исключения здесь . Я думаю, что это гораздо лучшее решение, так как вы можете сделать что-то с исключением и сообщить об этом, а не слепо скрывать все исключения, что приводит к чрезвычайно трудным поискам ошибок.

Это похоже на решение Скотта, но также добавляет обработчик событий в исключение Application.ThreadException, которое может произойти, если вы используете потоки. Вероятно, лучше использовать оба, чтобы перехватить все исключения.

3 голосов
/ 06 января 2009

См. Мой ответ здесь , который описывает некоторые компромиссы производительности, с которыми вам придется смириться, если вы будете использовать обработку исключений "поймай их всех".

Как сказал Скотт, лучший способ сделать то же самое - это событие UnhandledException. Я думаю, что Джефф на самом деле обсуждал эту проблему в раннем SO подкасте.

2 голосов
/ 06 января 2009

Я со StingyJack, не делай этого!

Однако, если боги на высоком указе, которые должны быть выполнены, то посмотрите мой ответ на этот вопрос Получить содержимое метода из файла cs

2 голосов
/ 06 января 2009

Прежде всего, я из StingyJack и Binary Worrier. Есть веская причина, по которой исключения не перехватываются по умолчанию. Если вы действительно хотите перехватывать исключения и умирать немного лучше, вы можете поставить блок try-catch вокруг вызова Application.Run() и работать оттуда.

При работе с внешними источниками (файлами, Интернетом и т. Д.) Следует (обычно) отлавливать определенные исключения (плохое соединение, отсутствующий файл, бла-бла). Однако в моей книге исключение где-либо еще означает 1) ошибку, 2) некорректную логику или 3) плохую проверку данных ...

Подводя итог, и чтобы полностью не ответить на ваш вопрос, вы уверены хотите ли вы это сделать?

1 голос
/ 06 января 2009

Я должен был сделать что-то похожее (добавить что-то к множеству строк кода); Я использовал регулярное выражение.

Я бы создал сценарий регулярного выражения, который нашел начало каждой функции, и вставил бы блок try catch сразу после начала. Затем я создал бы другой сценарий регулярного выражения, чтобы найти конец функции (путем нахождения начала функции сразу после нее) и вставить блок try catch в конце. Это не даст вам 100% пути, но оно достигнет, возможно, 80%, что, мы надеемся, будет достаточно близко, чтобы вы могли выполнить крайние случаи без излишней работы.

1 голос
/ 06 января 2009

Я хотел написать это как ответ на все ответы, тогда вы можете узнать об этом через вопрос RSS; Требование исходит от нашего технического лидера: вот его причина: нам не нужно выяснять, у какого func есть проблема в рабочем коде, о любой проблеме сообщалось как о предупреждении, мы помещаем уникальный код в блок ecery catch и видим, где проблема. Он знает, что есть глобальная обработка ошибок, но это не помогает в этом сценарии, и трассировка стека не выполняется в режиме выпуска, поэтому он требует блок try catch:

everyMethod(...){
    try
    {
    ..
    catch(Exception e)
    {
       RaiseAlert(e.Message.. blabla)
    }
}
1 голос
/ 06 января 2009

Если вы поместите вызов RaiseAlert в каждый метод, полученные вами стеки ошибок будут очень запутанными, если не неточными, при условии, что вы повторно используете методы. Метод регистрации должен действительно вызываться только в событиях или самом верхнем методе (ах). Если кто-то выдвигает вопрос о том, что обработка исключений должна быть в каждом методе, он не понимает обработку исключений.

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

Реализация AppDomain.UnhandledException является хорошей резервной копией, но единственным выходом для этого метода является уничтожение приложения после регистрации исключения. Чтобы предотвратить это, вам нужно написать глобальный обработчик исключений.

1 голос
/ 06 января 2009

так вот пример для тех, кто интересуется; 5006 уникален для этого метода;

public static LogEntry Authenticate(....)
        {
            LogEntry logEntry = null;
            try
            {
                ....
                return logEntry;
            }

            catch (CompanyException)
            {
                throw;
            }

            catch (Exception ex)
            {
                logEntry = new LogEntry(
                    "5006",
                    RC.GetString("5006"), EventLogEntryType.Error,
                    LogEntryCategory.Foo);

                throw new CompanyException(logEntry, ex);
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...