Определение места ошибки в исходном файле

Относительно недавно я писал про Singleton и там была у меня не решенная проблема с тем, что не выводилось точное место возникновения ошибки. Анализ ошибки проходил как надо, информация дополнительная выводилась, но это было мало. Привычный шаблон работы, когда двойной клик по тексту ошибки приводил к навигации на место ошибки не работал. Это безмерно огорчало.

После плодотворного общения с программистами PostSharp, оказалось, что это была ошибка в последней сборке и новый релиз, начиная с 4.0.41, ее исправляет. Дальше я хочу отдельно обратить внимание на то, что надо делать и рассказать немного о том, как вообще можно получить эту информацию в C#: до версии 4.5, с версии 4.5 и старше.

PostSharp

Эта часть статьи в целом задумана как обновление и привлечение внимания к статье про шаблон Singleton. Я ее обновил, но тем не менее.

Использование Архитектурного фреймворка из состава PostSharp рано или поздно приведет вас к тому, что надо будет уведомлять программистов об ошибках/недочетах. Лучше всего это делать с помощью специализированных классов, которые построены с учетом специфики работы PostSharp на этапе сборке проекта. К таким специализированным классам относятся:

  • MessageLocation – статический класс, который позволяет узнать место ошибки (строка, файл) на основе служебной информации о составной части класса (MethodInfo, ConstructorInfo и так далее).
  • Message – класс со статическими и динамическими методами, который помогает сформировать сообщение для отображения для конечного пользователя – программиста.

Общий шаблон работы с этими классами выглядит так:

Подробнее

WPF Exception Viewer

Сложность 100-200

Достаточно давно я писал о том, как работать (обрабатывать) с исключениями при использовании класса Task из Task Parallel Library (TPL), все описанные способы действительно работают и проверены на практике уже много раз и отлично меня спасают и упорядочивают работу с потоками, особенно с получением исключений. Однако тогда я упустил важный момент как еще централизованно можно получать исключения и никак не был освещен вопрос удобства работы с исключениями: отображение и коммуникация от пользователя. Сегодня собираюсь наверстать упущенное тем более под руку подвернулся удобный и простой набросок от MarkLTX с CodeProject.

Как оно бывает обычно

Обычно отчет об ошибке выглядит примерно следующим образом:

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

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

Так же пользователи не знаю, что текст можно копировать нажав Ctrl+C и высылают FullHD скриншот с ошибкой. Конечно весело порой посмотреть на чужие рабочие столы, но это быстро надоедает.

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

Подробнее

App Crash Handler

Может быть, вы замечали у себя в системе процесс GoogleCrashHandler.exe, который постоянно работает, появляясь в системе с установкой браузера Chrome. Долгое время где-то в подкорке постоянно крутилась мысль о том, как же он может работать. Интуитивно мне было понятно, что это относится к браузеру, что этот процесс отслеживает падения браузера и отсылает отчеты с параметрами падения, чтобы инженеры в Гугл могли оценить причины прекращения работы и принять какие-то решения по улучшению работы. Я не поддерживаю конспирологические теории на счет того, что с помощью этого процесса собирается приватная информация о пользователе.

Скриншот не с моей машины.

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

Исходя из названия и общей идеи мне стало интересно сделать свой «велосипед», так как коммерческие решения на рынке существуют, а вот о бесплатных я как-то не слышал. Да, есть программы у Microsoft (бесплатно) или у RedGate (платно), по которым тебе будут высылаться все отчеты об ошибках, которые возникли во время работы, но для этого нужно, чтобы пользователь нажал на кнопку «отправить данные». Зарегистрировать свою программу у вендора для участия в таком сборе. В корпоративном секторе, когда разработка внутренняя и градус паранойи повышен, такие варианты слабо прокатывают – все должно быть внутри и за пределы компании не выходить из соображений безопасности.

Идея

Почему это может быть важно для вас?

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

  • анализировать частоту возникновения ошибок
  • тип ошибок
  • можно сразу реагировать на ошибки, так как не требуется письма или звонка пользователя
  • писать автоматизированные отчеты о критических ошибках на основе данных в БД

В нашем случае надо будет подключить библиотеку, и вызвать только один метод. Остальное будет сделано программой, т.е. вам не придется описывать конфигурации того как ошибки будут писаться в базу или куда-то еще.

Подробнее

Обработка исключений при работе с классом Task

Сложность по шкале Microsoft 200

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

Далее будет рассмотрена работа с исключениями не только в теле метода, который был явным образом указан в качестве жертвы асинхронной работы, но и как получать исключения из вложенных асинхронных методов. Можете думать об этом как о сне во сне, и вспоминать фильм «Начало».

Все последующие примеры не открывают Америки и все прекрасно описано в книги  J.Albahari “C# in the Nutshell 4.0”, но пока не увидишь, как не надо делать, сложно бывает запомнить как надо.

Подробнее

MS SQL 2011 (Denali) — Throw

Служебное слово Throw (NEW)

Новое полезное дополнение для SQL Server 2011 (Denali) ­– выражение Throw. Разработчики на .Net уже догадались наверно, где и как оно будет использоваться.

Это слово может использоваться в сочетании с управляющей конструкцией Try…Catch и позволяет послать уведомление о возникновении ошибки времени исполнения. Когда возникает исключение, программа ищет ближайший по иерархии вверх блок Catch который может обработать исключение. Используя это выражение внутри блока Catch можно изменить вывод ошибки. Более того, теперь вызывать исключение можно произвольно в любом месте скрипта.

Далее рассмотрим различные способы поимки исключении, которые предоставляет SQL Server начиная с версии 2000.

Подробнее