Re[7]: Ассерты и дотнет
От: Sharowarsheg  
Дата: 05.06.15 19:39
Оценка:
Здравствуйте, Sinix, Вы писали:

S>То, что стандартные ассерты абсолютно не заточены под реальные сценарии.


Реальные сценарии-то разные у всех.

S>Политика "без ошибок" (при подключённом отладчике программный брякпойнт на нарушении ассерта), невозможность "проглотить" сработавший ассерт? Нет.

S>Интеграция с классическими if-then-throw? Нет.
S>Типовые хелперы, чтобы не дублировать сообщения, не ошибаться с проверками и не мучаться с локализацией? Нет.
S>Проверка для switch ... default:, чтобы не пропустить неподдерживаемые значения enum-ов? Нет.
S>Готовые хелперы для типовых случаев (неверный аргумент, неверное состояние, ошибка в биз-логике)? Неа.
S>Расширяемость (заточить под частные сценарии типа математики или IO)? Nope
S>Интеграция с JetBrains.Annotations? Ну, вы поняли
S>Интеграция с CodeContracts? Губозакаточные машинки в соседнем отделе.
S>Разные контексты для ассертов (отладка, продакшн, code metrics)? Ну хоть это с натяяяжкой да. Правда, на практике придётся столько писать, что сам Debug.Assert незаметен будет.

S>В общем, при желании конечно можно, но только с выдачей молока за вредность. Можно соком.


Ты хочешь себе набор фич под какое-то твое собственное использование, причем у тебя почему-то представление, что ассерт должен часто срабатывать, и представление, что все пользуются jetbrains и code contracts, или, по крайней мере, мечтают этим пользоваться.
Напиши себе под это набор своих функций с блекджеком и шлюхами, как ты и сделал, собственно, и вопрос остается только в названиях — можно ли это называть "ассерт", или нет?
Всякие прогрессивные молодежные течения, типа JetBrains, мне особо не интересны, а ты зачем-то их в требования впихнул. Как по мне, так чем меньше мусора, тем лучше. Сообщения? Зачем сообщения, когда есть stack trace? Какие разные контексты для ассертов? Как будто в дебаге нельзя на ноль делить, а в продакшне вдруг можно. Ассерты одинаковы во все времена, хоть в дебаге, хоть в релизе. И так по каждому пункту.
Re: Ассерты и дотнет
От: SergASh  
Дата: 05.06.15 19:57
Оценка: 40 (1) +1
Здравствуйте, Sinix, Вы писали:

Ошибочка имеется
messageFormat безо всяких проверок приходит из паблик-метода в FormatMessage. Если там будет null, то string.Format завалится.
Re[8]: Ассерты и дотнет
От: Sinix  
Дата: 05.06.15 20:25
Оценка:
Здравствуйте, Sharowarsheg, Вы писали:


S>Реальные сценарии-то разные у всех.

Угу, поэтому в стартовом посте выложил только то, что без особых изменений работает восьмой год в весьма разных проектах. Разумеется, везде ассерты допиливались под проект и все перечисленные выше фичи вместе встречались очень редко. Но каждая из них в своём проекте сэкономила кучу времени.


S>Ты хочешь себе набор фич под какое-то твое собственное использование, причем у тебя почему-то представление, что ассерт должен часто срабатывать, и представление, что все пользуются jetbrains и code contracts, или, по крайней мере, мечтают этим пользоваться.


Неа, эту часть не успел расписать подробно. Если коротко, работает закон больших чисел и тот же подход, что и в tdd: тесты должны упасть хоть один раз.
Т.е. _конкретный_ ассерт найдёт ошибку дай бог пару раз за жизнь софта, а вот ассерты в целом срабатывают регулярно.


S>Напиши себе под это набор своих функций с блекджеком и шлюхами, как ты и сделал, собственно, и вопрос остается только в названиях — можно ли это называть "ассерт", или нет?


Ну а что это такое, если оно работает в рантайме и служит для обнаружения ситуации "мы не угадали с нашими ожиданиями"?


S>Всякие прогрессивные молодежные течения, типа JetBrains, мне особо не интересны, а ты зачем-то их в требования впихнул.

Живая подсветка для возможных nullref exception, подсветка аргументов для format-методов. Если в компании уже используется решарпер, то не добавить поддержку в ассерты как-то глупо. Если нет — см выше, про "все фичи вместе встречались очень редко"

S> Как по мне, так чем меньше мусора, тем лучше. Сообщения? Зачем сообщения, когда есть stack trace? Какие разные контексты для ассертов? Как будто в дебаге нельзя на ноль делить, а в продакшне вдруг можно. Ассерты одинаковы во все времена, хоть в дебаге, хоть в релизе. И так по каждому пункту.

Ну т.е. вы тоже не используете ассерты на самом деле.

Сообщения спасают, когда у вас нет ни доступа к машине клиента, ни дампа, ни stacktrace толком, т.к. код клиента обфусцирован или клиент тупо не сумел отправить стек целиком. А бывает, сообщения приходят в виде распечатки скриншота с подписью "вынос разрешён" Энштейн, когда писал свою знаменитую цитату о бесконечности, явно не слышал про энтерпрайз. Увы, не корабль

Контексты для ассертов позволяют отделить сценарии "тут гарантированно будет работать" от "there be dragons". Для разных клиентов и для разных частей системы требования не совпадают. Например, ошибки в документе строгой отчётности недопустимы, в коде валидации "поле не пустое" — почему нет? Стоимость психологической травмы оператора от "поле не красное" и стоимость двухдневного простоя предприятия из-за того, что операторы в принципе не могут работать из-за сработавшего ассерта несколько несопоставимы

Кроме того, инварианты классов и прочие тяжёлые ассерты абсолютно недопустимы в массовых операциях, когда речь идёт о обработке тысяч/миллионов записей. В то же время возможность быстро и автоматически найти _точное_ место ошибки бесценна, т.к. экономит очень дорогие человекочасы. Сумеете совместить оба требования — смело патентуйте, пригодится.

Есть более специфичные (и на самом деле ещё более важные для бизнеса) моменты, но и этих хватит.
Re[2]: Ассерты и дотнет
От: Sinix  
Дата: 05.06.15 20:37
Оценка:
Здравствуйте, SergASh, Вы писали:


SAS>Ошибочка имеется

SAS>messageFormat безо всяких проверок приходит из паблик-метода в FormatMessage. Если там будет null, то string.Format завалится.
Угу. Как всегда, никто не поймал -> не было повода добавить красивую проверку.

На практике разницы конечно никакой, что null ref, что сработавший ассерт — всё одно печально. Это разновидность "MS07-052: Code execution results in code execution" (см пост от Рэймонда Чена), ассерт на ошибку в ассерте тут никак не поможет.

В понедельник посмотрю, емнип у нас такие вещи то ли решарпер, то ли code contracts ловят. Т.е. не всё так плохо
Отредактировано 05.06.2015 20:40 Sinix (Поправил ссылку) . Предыдущая версия .
Re: Ассерты и дотнет
От: мыщъх США http://nezumi-lab.org
Дата: 06.06.15 03:52
Оценка:
Здравствуйте, Sinix, Вы писали:

я один это прочитал как "атеисты и дотнет"?
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[2]: Ассерты и дотнет
От: DarthSidius  
Дата: 06.06.15 04:48
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>я один это прочитал как "атеисты и дотнет"?


Походу да.
... << RSDN@Home (RF) 1.2.0 alpha 5 rev. 58>>
♠♠♥♠♠♦♥
Re: Ассерты и дотнет
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.06.15 09:32
Оценка: 60 (1)
Здравствуйте, Sinix, Вы писали:

S>UPD2. Товарищи несогласные — не томите неизвестностью, мне ж интересно Что по-вашему не так?

Не то что бы не согласен, но есть пара копеечек.
По поводу BreakIfAttached().

Во-первых, оно по-моему немного не там. Я бы переместил его непосредственно перед throw в момент, когда исключения уже созданы, сообщения сформатированы, да и ближе по стеку к коду, вызвавшему хелпер, что удобнее при отладке.

Во-вторых, я наблюдаю явное злоупотребление Debugger.Break(). На этом подробнее.

Иерархия ArgumentException предназначена (это общеизвестно, но акцент не на этом) для возбуждения исключений в обстоятельствах неверно указанных параметров метода. И может показаться хорошей идеей остановить программу (при подключенном отладчике) для выяснения обстоятельств формирования недопустимых параметров. При определенных обстоятельствах это действительно отличная идея.
Но все-таки, возбуждение таких исключений — это часть поведения метода, которое неплохо бы протестировать (автоматическими тестами). Но BreakIfAttached внутри тестируемого кода говорит о том что мы не сможем пройти мимо этой строчки с отладчиком. Автоматический тест превращается в полуручной. Ладно, это можно не тестировать, ведь мы объявили в начале метода что sampleCount < 5000 не пройдет.

Но тут надо вспомнить что поведение метода (в том числе часть его поведения, выкидывающая исключения) может быть использовано для управления логикой более высокоуровневых компонент. Я не поклонник строить логику на исключениях, но еще меньше поклонник писать методы для проверки аргументов (без возбуждения исключений) для методов, которые возбудят исключения, если что не так. То есть, некоторое кол-во и качество параметров, так или иначе, зависит от пользовательского ввода, внешних данных, вызовов кода третьих лиц и т.п. И этот код в свою очередь может быть протестирован автоматическими тестами. (Да, я не пишу про юнит, здесь скорее ближе к интеграционным).
Я клоню к тому, что метод с BreakIfAttached внутри может в совершенно штатных условиях вызываться с неправильными параметрами, да еще и в цикле (не дай бог). Беда тому, кто будет пытаться отлаживать что-то другое, а BreakIfAttached будет останавливать отладку на чем-то тривиальном и оттестированном.

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

Так вот, о копеечках. Все что было выше — это не критика, это только контекст в рамках которого я предлагаю, или даже обращаю внимание на следующее:
Re[2]: Ассерты и дотнет
От: Sinix  
Дата: 06.06.15 11:46
Оценка:
Здравствуйте, samius, Вы писали:

S>По поводу BreakIfAttached().


S>Во-первых, оно по-моему немного не там. Я бы переместил его непосредственно перед throw в момент, когда исключения уже созданы, сообщения сформатированы, да и ближе по стеку к коду, вызвавшему хелпер, что удобнее при отладке.

Тоже вариант. Но не работает с контрактами емнип. От возни при отладке спасает [DebuggerHidden], отладчик прерывается на самом ассерте.

S>Во-вторых, я наблюдаю явное злоупотребление Debugger.Break(). На этом подробнее.


S>Иерархия ArgumentException предназначена (это общеизвестно, но акцент не на этом) для возбуждения исключений в обстоятельствах неверно указанных параметров метода. И может показаться хорошей идеей остановить программу (при подключенном отладчике) для выяснения обстоятельств формирования недопустимых параметров. При определенных обстоятельствах это действительно отличная идея.

Угу. На самом деле поведение настраивается — см свойство BreakOnException. И на релизных сборках это поведение по умолчанию отключено, т.к. усложняет жизнь разработчикам внешнего кода.

Вообще, я при возможности продавливаю политику "без ошибок": если у тебя ассерт сработал — в коде баг, остановись и поправь. Иначе дальше не пройдёшь
Разумной статистики толком нет, но если сравнивать части проекта, где ассерты применялись и часть, что написана до ассертов — во второй гдупых опечаток и ad hoc-костылей гораздо больше. Потому что ошибка находится позднее и исправить её, ничего не поломав, сложнее.

Главный бонус: в релиз уходят сборки без обнаруженных ошибок. Понятно, что не обнаруженные ошибки там есть, с этим ничего не сделать. А вот найденные, как правило, проще починить чем убедить тимлида, что на ошибку можно забить.
И ещё раз дисклаймер: это чисто наша внутренняя статистика и делать из неё глобальные выводы — нафиг-нафиг


S>Но все-таки, возбуждение таких исключений — это часть поведения метода, которое неплохо бы протестировать (автоматическими тестами). Но BreakIfAttached внутри тестируемого кода говорит о том что мы не сможем пройти мимо этой строчки с отладчиком. Автоматический тест превращается в полуручной. Ладно, это можно не тестировать, ведь мы объявили в начале метода что sampleCount < 5000 не пройдет.


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

Не может, если эта логика выражена ассертами. Ассерты — это документация факта "разработчик заложился на такое поведение". Т.е. сработавший ассерт означает ситуацию "поздно пить боржоми": ошибка уже случилась и решение выполнять код дальше ситуацию точно не улучшит

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


S>Я клоню к тому, что метод с BreakIfAttached внутри может в совершенно штатных условиях вызываться с неправильными параметрами, да еще и в цикле (не дай бог). Беда тому, кто будет пытаться отлаживать что-то другое, а BreakIfAttached будет останавливать отладку на чем-то тривиальном и оттестированном.


Бинго! Именно для этой ситуации BreakIfAttached и предназначен: намекнуть разработчикам на 100% баг в коде. Более тонкие намёки к сожалению не работают, т.к. "не наш код", "потом починим", "нам срочно" и тд.

Разумеется, на всякий пожарный это поведение можно выключить, но это именно аварийный выключатель, а не штука для "забей, само рассосётся".


S> при проверке аргументов и состояний следует уделять внимание тому, что бы отделять случаи, где требуется BreakIfAttached, от случаев, где следует вызывать хелперы без этого бонуса.

Мы этот вопрос решили просто: у нас нет таких ситуаций. За исключением ассертов для code metrics, те просто собирают статистику. Но это чисто экспериментальная штука и пока вообще непонятно, есть ли смысл в её использовании. Т.е. погоду не делает.

Уже писал, на всякий ещё раз: если в проекте допускается бросание исключений в промышленных масштабах — вы точно делаете что-то не так.

S> возможно стоит сделать static bool BreakOnException управляемой через app.config, тогда можно будет включать ее явно при отладке своего кода и отдавать налево выключенной по-умолчанию даже в #if DEBUG

Делалось. Резюме: влияет на качество кода в худшую сторону, т.к. догфудинг перестаёт работать. Рано или поздно разработчик забывает убрать настройку из аппконфига и в коммит уходят глупые ошибки.

Про отдавать налево отладочные сборки — ну а смысл отдавать сборку для обнаружения проблем с отключенным обнаружением проблем?

И ещё раз дисклаймер
Всё вышеперечисленное актуально чисто для наших проектов. Не подходит — никто не запрещает допилить под свои задачи, тем более что общая схема классов с ассертами и остальной код при этом не меняются.
Re[9]: Ассерты и дотнет
От: Sharowarsheg  
Дата: 06.06.15 13:54
Оценка: -1
Здравствуйте, Sinix, Вы писали:

S>>Реальные сценарии-то разные у всех.


Еще раз, разные сценарии разные везде.

S>>Ты хочешь себе набор фич под какое-то твое собственное использование, причем у тебя почему-то представление, что ассерт должен часто срабатывать, и представление, что все пользуются jetbrains и code contracts, или, по крайней мере, мечтают этим пользоваться.


S>Неа, эту часть не успел расписать подробно. Если коротко, работает закон больших чисел и тот же подход, что и в tdd: тесты должны упасть хоть один раз.


Или не работет. Почему ассерты должны падать хотя бы один раз? Изменится что-нибудь — упадут. Не изменится — не упадут.

S>>Всякие прогрессивные молодежные течения, типа JetBrains, мне особо не интересны, а ты зачем-то их в требования впихнул.

S>Живая подсветка для возможных nullref exception, подсветка аргументов для format-методов.

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

S>> Как по мне, так чем меньше мусора, тем лучше. Сообщения? Зачем сообщения, когда есть stack trace? Какие разные контексты для ассертов? Как будто в дебаге нельзя на ноль делить, а в продакшне вдруг можно. Ассерты одинаковы во все времена, хоть в дебаге, хоть в релизе. И так по каждому пункту.

S>Ну т.е. вы тоже не используете ассерты на самом деле.

Что значит "не используете"? У меня условия другие, и требования другие.

S>Сообщения спасают, когда у вас нет ни доступа к машине клиента, ни дампа, ни stacktrace толком, т.к. код клиента обфусцирован или клиент тупо не сумел отправить стек целиком.


У меня это всегда есть.

S>А бывает, сообщения приходят в виде распечатки скриншота с подписью "вынос разрешён"


А у меня не бывает.

S>Контексты для ассертов позволяют отделить сценарии "тут гарантированно будет работать" от "there be dragons".


Я предпочитаю не держать кода, в котором there be dragons.

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


Почему? Обрабатывайте правильно, и пусть весь мир подождет. Врядли клиенту нужен неверный результат, но зато быстро.

S>Есть более специфичные (и на самом деле ещё более важные для бизнеса) моменты, но и этих хватит.


Для вашего бизнеса, а для нашего другие важные, например тривиальность написания этого самого ассерта. Assert(x>0) и всё. Чтобы я сам себе писал такое пояснение —

"TODO: 'Repeat zero times' usually means that there's an logical error. \r\n"+
"At the same time sampleCount=0 could be threated as 'just skip it', so no zero policy would lead to weird checks across the codebase. \r\n" +
"We need more samples from real code to do the proper decision."


невозможная вещь, слишком долго писать, проще код сделать правильно.
Re[10]: Ассерты и дотнет
От: Sinix  
Дата: 06.06.15 15:04
Оценка: +2
Здравствуйте, Sharowarsheg, Вы писали:

S>>>Ты хочешь себе набор фич под какое-то твое собственное использование, причем у тебя почему-то представление, что ассерт должен часто срабатывать, и представление, что все пользуются jetbrains и code contracts, или, по крайней мере, мечтают этим пользоваться.


Для кого я дисклаймеры выше по ветке писал? Диалог получается примерно такой: "Мы сделали так, как нам удобно" — "Почему вы сделали так, как удобно вам?"

Да, и решарпер, и контракты, и ассерты здорово экономят время, т.к. позволяют находить ошибки практисски в реалтайме. На больших проектах это важно, т.к. ошибка найденная в процессе написания кода и ошибка, проползшая в тестирование, требуют несколько разных усилий для исправления. Если это неочевидно — я искреннне завидую

S>Всё равно не интересно, равно как и решарпер. Решарпер, при последних испытаниях, регулярно предлагал рефакторить работающий код в неработающий, отказались от него.

А просто отключить лишнее не пробовали? Подход "всё или ничего" в больших масштабах не работает, приходится искать компромиссы.


S>>> Как по мне, так чем меньше мусора, тем лучше. Сообщения? Зачем сообщения, когда есть stack trace? Какие разные контексты для ассертов? Как будто в дебаге нельзя на ноль делить, а в продакшне вдруг можно. Ассерты одинаковы во все времена, хоть в дебаге, хоть в релизе. И так по каждому пункту.

S>>Ну т.е. вы тоже не используете ассерты на самом деле.

S>Что значит "не используете"? У меня условия другие, и требования другие.

Ну да, об этом и речь — для вас некритична половина фич, ради которых и используют ассерты. Это всё равно как на примере мопеда доказывать ненужность ремней безопасности. Разные условия — разные решения.


S>Почему? Обрабатывайте правильно, и пусть весь мир подождет. Врядли клиенту нужен неверный результат, но зато быстро.

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

S>Для вашего бизнеса, а для нашего другие важные, например тривиальность написания этого самого ассерта. Assert(x>0) и всё. Чтобы я сам себе писал такое пояснение —

"TODO: 'Repeat zero times' usually means that there's an logical error. \r\n"+
"At the same time sampleCount=0 could be threated as 'just skip it', so no zero policy would lead to weird checks across the codebase. \r\n" +
"We need more samples from real code to do the proper decision."

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

S>невозможная вещь, слишком долго писать, проще код сделать правильно.

Разумеется. Если последствия ошибок не расползаются примерно по трём сотням проектов. После этого исправить ошибку обычно посложнее, чем собрать статистику _до_ внесения потенциально ломающих изменений
Re[3]: Ассерты и дотнет
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.06.15 11:28
Оценка: 3 (1) +1
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, samius, Вы писали:


S>>Во-первых, оно по-моему немного не там. Я бы переместил его непосредственно перед throw в момент, когда исключения уже созданы, сообщения сформатированы, да и ближе по стеку к коду, вызвавшему хелпер, что удобнее при отладке.

S>Тоже вариант. Но не работает с контрактами емнип. От возни при отладке спасает [DebuggerHidden], отладчик прерывается на самом ассерте.
Хорошо, коль так. Не работал c [DebuggerHidden] вообще, да и CC не прижился у нас.

S>>Иерархия ArgumentException предназначена (это общеизвестно, но акцент не на этом) для возбуждения исключений в обстоятельствах неверно указанных параметров метода. И может показаться хорошей идеей остановить программу (при подключенном отладчике) для выяснения обстоятельств формирования недопустимых параметров. При определенных обстоятельствах это действительно отличная идея.

S>Угу. На самом деле поведение настраивается — см свойство BreakOnException. И на релизных сборках это поведение по умолчанию отключено, т.к. усложняет жизнь разработчикам внешнего кода.
Хорошо что настраивается, но в опубликованном варианте оно или включается для ВСЕГО кода, или выключается для всего же. Т.е. никаких scope по типам, нет возможности конфигурировать. Все это навесное, конечно.

S>Вообще, я при возможности продавливаю политику "без ошибок": если у тебя ассерт сработал — в коде баг, остановись и поправь. Иначе дальше не пройдёшь

S>Разумной статистики толком нет, но если сравнивать части проекта, где ассерты применялись и часть, что написана до ассертов — во второй гдупых опечаток и ad hoc-костылей гораздо больше. Потому что ошибка находится позднее и исправить её, ничего не поломав, сложнее.

S>Главный бонус: в релиз уходят сборки без обнаруженных ошибок. Понятно, что не обнаруженные ошибки там есть, с этим ничего не сделать. А вот найденные, как правило, проще починить чем убедить тимлида, что на ошибку можно забить.

S>И ещё раз дисклаймер: это чисто наша внутренняя статистика и делать из неё глобальные выводы — нафиг-нафиг
да +1

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

S>Не может, если эта логика выражена ассертами. Ассерты — это документация факта "разработчик заложился на такое поведение". Т.е. сработавший ассерт означает ситуацию "поздно пить боржоми": ошибка уже случилась и решение выполнять код дальше ситуацию точно не улучшит

S>Нужно строить логику на исключениях — просто бросайте, ассерт тут не нужен. И хелперы тоже: если в проекте так много подобной логики, что нужны хелперы — у проекта куда более серьёзные проблемы

Вот! Этого просто не прозвучало в заглавном посте. Там было "Косяк с настройкой объекта." Но сегодня это такой косяк, что встань и поправь немедленно, а завтра в штатной ситуации окажется 10 из 200 косячных настроек. Т.е. я только к тому и призывал, что не нужно пихать в Assert-ы все исключения и медитировать над тем, где это действительно "встань и поправь", или исключение может быть частью логики caller-а.

S>>Беда тому, кто будет пытаться отлаживать что-то другое, а BreakIfAttached будет останавливать отладку на чем-то тривиальном и оттестированном.


S>Бинго! Именно для этой ситуации BreakIfAttached и предназначен: намекнуть разработчикам на 100% баг в коде. Более тонкие намёки к сожалению не работают, т.к. "не наш код", "потом починим", "нам срочно" и тд.


S>Разумеется, на всякий пожарный это поведение можно выключить, но это именно аварийный выключатель, а не штука для "забей, само рассосётся".

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

S>> при проверке аргументов и состояний следует уделять внимание тому, что бы отделять случаи, где требуется BreakIfAttached, от случаев, где следует вызывать хелперы без этого бонуса.

S>Мы этот вопрос решили просто: у нас нет таких ситуаций. За исключением ассертов для code metrics, те просто собирают статистику. Но это чисто экспериментальная штука и пока вообще непонятно, есть ли смысл в её использовании. Т.е. погоду не делает.

И тут тоже дисклаймер бы еще раз... ))

S>Уже писал, на всякий ещё раз: если в проекте допускается бросание исключений в промышленных масштабах — вы точно делаете что-то не так.

Это слишком категоричное суждение (без упоминания дисклаймера непосредственно в теле суждения). Допустим, мы пишем промышленный сервис конвертер или рендерер файлов. Промышленный — означает что файлы на него будут поступать в промышленных масштабах. Масштаб количества файлов, которые имеют (мягко говоря) неожиданности для разработчика конвертера этого формата, тоже выходит промышленным. Особенно если формат широко распространен. Здесь все приобретает промышленные масштабы, даже OOME.
Выручает лишь что-нибудь типа ElasticSearch, для того что бы отделять исключения более промышленного масштаба от менее промышленного.

S>> возможно стоит сделать static bool BreakOnException управляемой через app.config, тогда можно будет включать ее явно при отладке своего кода и отдавать налево выключенной по-умолчанию даже в #if DEBUG

S>Делалось. Резюме: влияет на качество кода в худшую сторону, т.к. догфудинг перестаёт работать. Рано или поздно разработчик забывает убрать настройку из аппконфига и в коммит уходят глупые ошибки.
Благодарю за опыт.

S>Про отдавать налево отладочные сборки — ну а смысл отдавать сборку для обнаружения проблем с отключенным обнаружением проблем?

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

S>И ещё раз дисклаймер

S>Всё вышеперечисленное актуально чисто для наших проектов. Не подходит — никто не запрещает допилить под свои задачи, тем более что общая схема классов с ассертами и остальной код при этом не меняются.
Во, не меняется. Но не меняется относительно чего? Мы в свое время Debug.Assert-ов вкусили, долго плевались. Допускаю, что использовали в том числе не по делу, но экспериментировать с ними дальше желания не получили. В итоге, assert-ы у нас, конечно есть, но это в большей части хелперы, не заигрывающие с отладичиком и вниманием разработчика, тем более посреди прогона тестов.
То есть идея мне показалась интересной и здравой, но отсутствие оговорок про схему классов с ассертами и остальной код (а так же отсылки к этой схеме) меня и возбудило. Есть какой-то гайдлайн на заметке, когда ассерт, а когда нет?
Re[2]: Ассерты и дотнет
От: Sinix  
Дата: 08.06.15 08:28
Оценка:
Здравствуйте, SergASh, Вы писали:

SAS>Ошибочка имеется

SAS>messageFormat безо всяких проверок приходит из паблик-метода в FormatMessage. Если там будет null, то string.Format завалится.

S>>В понедельник посмотрю, емнип у нас такие вещи то ли решарпер, то ли code contracts ловят. Т.е. не всё так плохо.

Угу, проверил — решарперовский [NotNull] стоит.
Re: Ассерты и дотнет
От: SergASh  
Дата: 08.06.15 09:35
Оценка:
Здравствуйте, Sinix, Вы писали:

В том посте полуторагодичной давности утверждалось следующее:

При подключенном отладчике немедленно прерывать выполнение прямо в точке где нарушается ассерт (а не внутри ассерта) и не пускать дальше, пока не поправишь ошибку.

Интересует выделенный фрагмент. Как вы этого достигаете?
Одного DebuggerHidden для этого мало. Отладчик останавливается на Code.NotNull, но если нажать F10 или F5, то дальше выполнение продолжается как обычно
Re[2]: Ассерты и дотнет
От: Sinix  
Дата: 08.06.15 09:48
Оценка:
Здравствуйте, SergASh, Вы писали:

При подключенном отладчике немедленно прерывать выполнение прямо в точке где нарушается ассерт (а не внутри ассерта) и не пускать дальше, пока не поправишь ошибку.

SAS>Интересует выделенный фрагмент. Как вы этого достигаете?
SAS>Одного DebuggerHidden для этого мало. Отладчик останавливается на Code.NotNull, но если нажать F10 или F5, то дальше выполнение продолжается как обычно

Просто попробуйте на студии с настройками по умолчанию. Секрет в комбинации [DebuggerHidden] + stack unwinding.
Re[3]: Ассерты и дотнет
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 08.06.15 10:27
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Sharov, Вы писали:


S>>>Готовые ассерты (Debug.Assert) на мой взгляд могут использовать только мазохисты. В них _всё_ сделано неправильно.


S>>Это еще почему?

S>Потому что эта реализация не решет проблемы, которые по идее должны решать ассерты?

Какие проблемы должны решать ассерты ? Каким образом ?
Re[10]: Ассерты и дотнет
От: Sharov Россия  
Дата: 08.06.15 11:09
Оценка:
Здравствуйте, Sharowarsheg, Вы писали:

S>Всё равно не интересно, равно как и решарпер. Решарпер, при последних испытаниях, регулярно предлагал рефакторить работающий код в неработающий, отказались от него.


А не надо ставить последнюю версию. Последнюю версию надо ставить через годик-полтора. jb как ms, раньше
первого сервис пака шевелиться не стоит.
Кодом людям нужно помогать!
Re[10]: Ассерты и дотнет
От: Venom  
Дата: 09.06.15 04:07
Оценка:
Здравствуйте, Sharowarsheg, Вы писали:

S>Всё равно не интересно, равно как и решарпер. Решарпер, при последних испытаниях, регулярно предлагал рефакторить работающий код в неработающий, отказались от него.


Речь, наверное, про конверт foreach'ей в linq с let'ами или без них?
Даже если нет, то отключаемо/комментируемо.
Отредактировано 09.06.2015 4:09 Venom . Предыдущая версия .
Re: Ассерты и дотнет
От: Venom  
Дата: 09.06.15 04:22
Оценка:
Здравствуйте, Sinix, Вы писали:

S> "TODO: 'Repeat zero times' usually means that there's an logical error. \r\n"


Скорее придирка, но тем не менее.
Как насчет Environment.NewLine?

Далее, дурацкий вопрос:
Что будет, если Вася вставит в код вместо коммента что-нибудь, что нарушает условия проверки SampleCount:
        public void Run<T>(T value) where T: class
        {
            Code.NotNull(value, "value");
            Code.AssertState(SampleCallback != null, "Fill SampleCallback first!");
        
            // Тут был Вася
            SampleCount = 9001;            

            for (int i = 0; i < SampleCount; i++) // (0)
            {
                SampleCallback(value.ToString()); // (1), (2)
            }
        }

Я так понимаю мы не гарантируем целостность внутри метода, а проверяем входные данные, т.е. действуем а-ля CodeContracts/guard clauses из ФП.
Как можно решить такую проблему? (вопрос скорее философский, но тем не менее, интересно твоё мнение)
Отредактировано 09.06.2015 5:06 Venom . Предыдущая версия . Еще …
Отредактировано 09.06.2015 5:05 Venom . Предыдущая версия .
Отредактировано 09.06.2015 4:24 Venom . Предыдущая версия .
Re[11]: Ассерты и дотнет
От: Sharowarsheg  
Дата: 09.06.15 04:57
Оценка: 1 (1)
Здравствуйте, Venom, Вы писали:

S>>Всё равно не интересно, равно как и решарпер. Решарпер, при последних испытаниях, регулярно предлагал рефакторить работающий код в неработающий, отказались от него.


V>Речь, наверное, про конверт foreach'ей в linq с let'ами или без них?


Нет, кажется. Мне помнится что-то про вынесение методов. Linq у меня нету вообще.
Re[7]: Ассерты и дотнет
От: Venom  
Дата: 09.06.15 05:08
Оценка:
Здравствуйте, Sinix, Вы писали:

S> т.е. контракты с ассертами сочетаются без проблем.


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