vitus_wagner (
vitus_wagner) wrote2017-03-15 09:37 am
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Entry tags:
Semantic locality
http://esr.ibiblio.org/?p=7421
Раймонд умный пост написал по поводу концепций, которые лежат под Unix way. Я эту мысль про семантическую локальность три дня думать буду.
Раймонд умный пост написал по поводу концепций, которые лежат под Unix way. Я эту мысль про семантическую локальность три дня думать буду.
no subject
no subject
На этом месте мне вспомнился чудовищных размеров флейм с КЫВТа, где люди (в том числе те, кто компиляторы пишут, а не энтерпрайз какой) спорили о сравнительном удобстве и производительности между передачей кодов ошибок, как в Golang и исключениями, как много где. В теории, исключения лучше, если они реализованы правильно, и особенно они хороши в случае вызовов с в 40 уровнями вложенности в стеке, когда программист попросту устанет передавать ошибку наверх руками.
В типичном же unixway вряд ли можно встретить цепочку, где вызывалось бы больше 5 утилит. Вдобавок, нет никакого механизма "исключений", которые летали бы между процессами (и слава богу, наверное).
Чего нет в типичных пайпах - так это общепринятых границ сообщений. Даже для потоковых данных может появиться смысл в передаче данных некими кусками, chunk'ами. В виндовых named pipes есть механизм передачи отдельных сообщений, в юниксах же, насколько мне известно, подобное есть только в d-bus. Самостоятельно сделать разбивку на сообщения несложно, но - каждый раз это все равно нужно делать, и всякий будет делать это по-своему.
no subject
Вот, блин, с тех пор как плохих программистов научили пользоваться исключениями, сообщения об ошибках везде, от файрфокса до банкоматов стали абсолютно неинформативными. Потому что за сорок уровней раскрутки стэка теряется контекст, и приходится выводить сообщение вида "у вас случилась полнейшая фигня". Еще привычку завели в этом сообщении давать единый на все случаи жизни длинный текст про наиболее частые ошибки. Не про случившуюся, а про наиболее частые.
Например банкомат вместо "у меня сейчас нет достаточного количества купюр нужного достоинства" говорит "вы ввели неправильную сумму", хотя я ее не вводил, я ее из его же собственной менюшки выбрал.
Почему-то паттерна обработки ошибок вида "навесить на исключение дополнительный контекст, предназначенный для обработчика более высокого уровня и передать дальше" не применяют. Хотя по умолчанию интерпретаторы и компиляторы делают именно такой stack trace. Но не машинночитаемый и не пользователечитаемый.
Система с кодами ошибок провоцирует, хотя и неявно именно такое поведение - донести наверх, до обработчика именно содержательный смысл ошибки, выдать такое сообщение. на которое кто-то (вышележащий код или пользователь) сможет осмысленно отреагировать.
no subject
... Наше будущее лучезарно как никогда ...
no subject
no subject
no subject
Тут в общем-то выхода нет. Если у тебя ошибки обрабатываются через исключения, то нужно показывать пользователю результат обработки stack trace. Причем не абы какого, а умного. Т.е. на входе в каждую функцию добавлять в этот стэк ту содержательно важную информацию, которая потребуется для устранения проблемы, если вдруг в этом месте проихошла ошабка. Например при входе в функцию открытия файла - имя файла.
Но так никто не делает. В результате чего в распоряжении обработчика ошибок есть только тип ошибки, который без этой дополнительной информации мало что пользователю говорит, и тот самый stack trace который показывать нельзя.
Что остается делать? Только показывать сообщение от балды "у нас тут все настолько плохо, что мы уже сами не можем понять, что именно не так. Но попробуйте это, это и это - вдруг поможет".
no subject
А вот криворукие программисты могут и такое делать, как выше сказано, да.
no subject
foo[bar(..)]
нам прилетает какой-нибудь IndexOutOfBound, из за того, что внутри bar действительно ошибка есть(алгоритм неправильно написали), то мы не можем ничего разумного в текст написать, т.к. мы про этот факт не знаем и можем думать, что сами из foo неправильный индекс достать пытаемся.
А текст исходной ошибки в данном случае явно ничего умного не скажет.
no subject
no subject
Из логики "индекса в массиве не нашлось, значит, пользователь неправильное значение ввел. Ловим исключение и по нему ругаемся."
А тут внезапно индекс не нашелся где-то глубже по вызовам и поэтому все сломалось.
no subject
1. Проверяем индекс ("индекса в массиве не нашлось, значит, пользователь неправильное значение ввел"), и если он плохой - внятно ругаемся
2. "Ловим исключение и по нему ругаемся" -- опять же внятно.
3. Прокидываем исключение выше, там пишут 500 Internal Server Error
4. Показываем пользователю кишки системы, а также кровь, распидарасило и стектрейс
no subject
try
... = foo[bar()]
catch IndexOutOfBound
ShowMessage("У вас нет такого номера счета")
Мы вот решили поймать исключение при индексировании foo и внятно выругаться.
Семантика у foo такая, что если в нем чего-то нет, то пользователь не тот счет ввел
Вот только оказалось, что исключение прилетело не от нашего индексирования, а из глубин bar.
И все - при какой-то совершенно посторонней ошибке пользователю показывается "У вас нет такого счета".
А потом еще интефейс усовершенствовали, чтобы вводить ничего не надо, а надо выбрать из списка, но проверку оставили.
no subject
no subject
Это демонстрация того, как я понял утверждения хозяина журнала о потере контекста - что одно и то же исключение, которое бросилось тут и или там, нужно как-то различать , но это немного затруднительно.
no subject
Исключение OutOfBounds не имеет никакого бизнес-смысла само по себе, откуда бы оно ни вылетело. Оно может обрести такой смысл только после анализа инцидента разработчиками.
Однако, во многих случаях и глубокоуровневый код имеет возможность выкинуть исключение с бизнес-смыслом. Хотя бы ValidationFailedOutOfBoundsException extends ArrayIndexOutOfBoundsException - кому надо, может его поймать особым образом с учётом его бизнес-смысла, а кто не может - тот обработает его как техническое ArrayIndexOutOfBoundsException. Контекстом в данном случае будет точный подкласс и дополнительные его поля.
no subject
no subject
no subject
У любой системы, взаимодействующей с реальным миром, бывают случаи когда операцию выполнить нельзя из-за проблем, которые не во власти системы. Но очень часто - во власти пользователя. И основная моя претензия в том, что пользователю не выдается внятной информации о том, что делать в тех случаях, когда он что-то делать может. Ну или внятной информации о том, что делать бесполезно.
Возвращаясь к тому же банкомату - если в нем осталось 3 тысячных купюры, а пользователь запросил 4.5 тысяч, то при получении сообщения "Непрпавильная сумма" он скорее всего пойдет и выберет из менюшки 5 тысяч. Которых ему все равно не дадут, потому что их просто нет. А получи он сообщение "у меня осталось только три тысячи", он их и снимет.
Кстати, банкомат который вменяемо указывает сколько денег можно снять, я видел. Причем он хитрый, указывает сумму по-моему не более 2/3 оставшихся денег, чтобы следующему хоть что-то осталось.
no subject