![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| 0leg |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 23.11.2006 Репутация: 1 Всего: 1 |
Ситуация:
Проект состоит из основного приложения, которое работает с базой данных через интерфейс IDatabase. Есть несколько классов, реализующих IDatabase для различных типов СУБД. Эти классы предполагается писать на стороне, без доступа к исходникам основного приложения (в том смысле, что менять исходники под новые классы никому нельзя). Необходимо создать общий механизм обработки исключений, чтобы выполнялись условия: 1. Исключения должны записываться в единый лог-файл приложения. 2. Должна быть возможность идентифицировать каждое исключение, чтобы обрабатывать каждое исключение по-своему. Создавать для каждой ошибки свой класс не могу - число ошибок может быть до сотни. Я реализовал это так: Создал новый класс исключений, от которого будут наследоваться все остальные. В этом классе реализовал новое совйство ErrorCode (для хранения уникального кода ошибки) и переписал конструкторы, чтобы они принимали на вход код ошибки и лог-файл для записи сообщения:
Новый конструктор делает следующее: 1. Запоминает код ошибки (теперь он будет доступен через свойство ErrorCode). 1. В зависимости от кода ошибки формирует нужное сообщение. 2. Делает запись в лог-файл. Теперь создаю несколько наследников CommonException (без дополнительного кода). Один из наследников - для ошибок при работе с базами:
Предполагается, что исключения DBException будут генерироваться классами, реализующими интерфейс IDatabase. Но тут возникает ПРОБЛЕМА: Базовое приложение не знает заранее коды ошибок, которые будут генерироваться внешними классами (класс может быть еще не написан) и не сможет правильно сформировать по ним сообщение. Помогите решить проблему по-изящнее. Возможно ли обойтись без кодирования ошибок? Мне кодирование нужно по двум причинам: 1. По коду я формирую сообщение. Может правильнее формировать сообщение на месте вызова? Но тогда ухудшается читабельность кода. 2. По коду я определяю дальнейшие действия (не все ошибки фатальные - некоторые нужно просто записать в лог, определенным образом обработать и продолжить выполнение приложения). |
||||
|
|||||
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Обычно, для записи в лог используется Message из исключения; выкинуть исключение можно в любом месте кода и с любым, произвольным сообщением (см. конструктор со строковым аргументом). Для обработки конкретного исключения используется catch на тип исключения или его родительский тип. ИМХО, числовой код не нужен, разве что исключений сотни и обрабатываются они по отдельности (лень писать кучу классов и catch-ей на каждый). Хотелось бы увидеть пример такого исключения и кода, который его обрабатывает. -------------------- ![]() |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Варианты:
1) Вся информация нужная для записи в лог и определения критична ли ошибка содержится в самой ошибке. Поля: LogMessage и ExceptionType, например. Какая разница что писать код ошибки или полную информацию о ней 2) Можно передавать ошибку в специальный класс-обработчик, который придется изменять по мере добавления новых. Но с другой стороны ты меняешь только его, а не основное приложение. P.S. Мне больше нравится второй вариант. |
|||
|
||||
| 0leg |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 23.11.2006 Репутация: 1 Всего: 1 |
про конструктор - в курсе могут быть именно сотни (по-крайнер мере одна сотня). В том и проблема, что для нескольких ошибок хотелось использовать одно исключение, но имеющее какой-то признак, уточняющий характер ошибки.
А если новые ошибки добавляю не я? А несколько незнакомых со мной и друг с другом человеков? Это некрасиво. Я хочу как с интерфейсами - описал интерфейс и всё! реализуйте его как хотите, меня не трогайте. Я за полное разделение труда. Можно пойти на изврат - написать класс с run-time добавлением новых сообщенией. Но это уже слишком... ---- Насчет генерации сообщений по месту ошибки: возможно так и сделаю. Вопрос с идентификацией ошибок пока не закрыт......!!! |
||||
|
|||||
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Но ведь в случае с кодами ошибок, если добавится например ошибка ERROR_DBCONNECTION_CLOSED, придётся лезть во все места где есть DBException и вставлять ещё один if ! Какое же тут разделение труда, если все человеки будут рефакторить код на каждый чих. Хорошей практикой является не допускать ошибочных ситуаций вообще, а если случаются - обрабатывать по возможности ближе к месту возникновения. Тогда кучи кодов ошибок, проверок и ответных действий в catch-е не будет. -------------------- ![]() |
|||
|
||||
| ivashkanet |
|
||||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Хочешь интерфейс? Пожалуйста:
Но лучше создать иерархию классов:
P.S. Хотя я считаю, что первоначальную обработку исключения должен проводить класс в котором оно было сгенерировано. Незачем посторонним (и не очень) класса знать подноготную другого. Вот если он не в состоянии это сделать, тогда да... Добавлено @ 12:09 Вот и я об этом |
||||
|
|||||
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
ivashkanet, одна поправка: ex.Message нельзя использовать для проверки, Message не для этого предназначен. Если кто-то не знает о том, что Message предполагается проверять в свитче, то может написать к примеру:
после чего exception processor-у останется виновато развести руками -------------------- ![]() |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
mr.DUDA, нет, нет, нет
Я просто выбрал первое попавшееся текстовое (string) поле класса Exception Не писать же ex.ErrorCode если в классе Exception этого свойства нет P.S. Извиняюсь, что ввел в заблуждение. Добавлено @ 14:07 |
|||
|
||||
| 0leg |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 23.11.2006 Репутация: 1 Всего: 1 |
Спасибо за ответы, помогли упорядочить моск.
Итак, задача вкратце: Есть основное приложение, оно работает с базой данных посредством одного интерфейса - IDatabase. Есть куча классов, реализующих интерфейс IDatabase. Основное приложение будет выбирать нужный класс для IDatabase в run-time. При написании классов код основного приложения менять уже будет нельзя. Вопрос: как обрабатывать исключения и записывать их в единый лог. Решил делать так: 1. Пишу общего предка для всех своих исключений, который пишет лог-файл:
2. На основе CommonException создаю остальные исключения - и для основного приложения, и для подключаемых внешних классов. Все классы исключений помещаю в общедоступную библиотеку. 3. В месте возникновения ошибки генерирую исключение и сразу передаю в конструктор сообщение об ошибке. 4. Если ошибка не критическая - исключение не генерирую, самостоятельно пишу в лог сообщение, самостоятельно вывожу окно с сообщением на экран(если необходимо). 5. Все ошибки, для которых нужна особая обработка (например, пароль непрошел - нужно ввести пароль еще раз) реализую отдельными классами. Остальные - объединяю по несколько ошибок на класс, просто будут разные сообщения. Если что - поправьте. |
|||
|
||||
| Exception |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 4525 Регистрация: 26.12.2004 Репутация: 29 Всего: 186 |
ИМХО, не стоит изобретать велосипед. Exception Handling Block, входящий в состав Enterprise Library.
Небольшая статья о нём. |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |