Pull to refresh

Comments 19

Уже ж закопали. Или премодерация заняла три месяца?

Что ж, подыграю вам.

Каждый очередной подобный «proposal» — в очередной раз подсвечивает ущербность этого языка. Я вот читал статью и меня постоянно немного тошнило от вещей, которые автор описывает с восторгом.
В любом случае интересно наблюдать за всей этой историей с обработкой ошибок в go. Многие просто смеются над гошникамии и говорят, что они никак не могут осилить обычный try/catch, но и этот подход хоть и самый популярный, но не общепризнанный. В haskell, например, не особо любят эксепшены и предпочитают всякие MayBe и Either. Интересно, чем это закончится. Может, Пайк придумает нечто совсем революционное.

В Хаскеле как бы есть языковые средства, которые делают Either таким же удобным как исключения...

Никто и не спорит. Мне вообще обработка ошибок в хаскеле больше нравится, чем обычные try/catch.
— Давайте откажемся от исключений!
— Да-да, исключения зло, использование их для управления потоком исполнения надо карать страшными карами!
— Фигня выходит, давайте добавим try чтобы не писать кучу тупого кода на каждый вызов каждой функции?
— Да, давайте…

— Давайте не будем вводить исключения, чтобы не усложнять язык
— Да, если писать идиоматичный код, то он выходит линейным и понятным любому человеку (вспомним ещё, что гугл использует C++ без исключений, к примеру), поэтому нет никакого смысла включать их в дизайн
— Вот есть много людей, которые не привыкли к языкам без встроенного механизма исключений, к тому же Go эволюционировал и теперь на нём пишут много различных программ. Может быть, подумаем над механизмом, который бы позволил помочь людям по-прежнему писать понятный код, но сделал его более компактным?
— Да, хорошая идея.
— Постойте! Может быть, поязвим над тем какие глупые авторы языка, который создавался с определенными целями и в определенных условиях, и надо было исключения добавить как у всех?


P.S. Я не говорю что этот proposal хороший. Но код на Go можно писать читаемым и без исключений, если не тащить с собой характерные принципы другого языка и говорить что это язык плохой. Это в принципе относится к любому языку, в прочем.


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

UFO landed and left these words here

Да вроде понятно же всё. (T1, T2, ..., Tn, E) -> Either E (T1, T2, ..., Tn)

Самое хорошее в этом proposal — что его все-таки закрыли.


Самое плохое — что такое поведение поощряло бы проброс ошибок наверх (привет исключениям) вместо их надлежащей обработки (см. Errors are values).

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


Принцип самурая — то, как нужно жить.

А когда надлежащая обработка может быть произведена на несколько десятков уровней выше за неимением всего контекста?

Выравнивать весь код в один уровень? На каждом уровне писать специфическую реакцию на «обработку» ошибок нижним уровнем? У меня упал http с кодом 404, мне в http либу встроить отрисовку gui с сообщением об ошибке, или все же выкинуть ошибку куда то повыше, например в часть кода с gui?

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


Я скорее о том, что если у нас во время работы с базой возникла ошибка sql.ErrNoRows, то, скорее всего, эта ошибка не должна лететь до контроллера и не должна специально обрабатываться там. Ошибка уровня sql.ErrNoRows вообще вряд ли должна покидать пределы пакета работы с базой данных — пакету контроллера вообще незачем знать, что за ошибка (sql.ErrNoRows, mongo.ErrNoDocuments, ...) была изначально. Важно то, что это была, например, ошибка storage.ErrNotFound, созданная на уровне работы с базой в результате обработки ошибки.

Т.е. делать то же что и делают exceptions, только с заменой try catch throw на if switch .(type) return, и невозможностью автоматически пропустить ошибку с уровня возникновения на уровень реагирования, минуя промежуточные уровни? Хорошая обработка ошибок :)

автоматически пропустить ошибку с уровня возникновения на уровень реагирования

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


Если для вас в конкретной ситуации нормально, что package1 выставляет как своё api ошибки из совершенно левого package2, то, конечно, пробрасывайте ошибки, как они есть. Просто это не всегда вариант.

Как-то в питонячьей практике удается обходиться стандартными Value/Key/IndexError, requests.HTTPError и django.ModelDoesNotExist. Очень редко когда нужны кастомные ошибки; обычно свои иерархии исключений возникают в клиентах к какому-нибудь API (будь то HTTP или RabbitMQ). Есть ужасный антипаттерн ловить базовый Exception, однако и он бывает востребован в случае "уже 5 тип ошибки, который надо ловить и обрабатывать также как и остальные".

Я просто к чему веду — вся эта свистопляска с error в golang не уменьшает количество кода сделанного в ручную(иногда — наоборот), не упрощает жизнь, не улучшает и не стимулирует обработку ошибок так, как это описывают в хвалебных статьях о golang… Смысл этого всего?)

Забавно, что семантика тут такая же, как у оператора? из Rust. А тот является стабилизированной, встроенной в язык версией макроса try!(). Макрос try!() есть в Rust с 1.0 (больше 4 лет), и реализацию из пяти строк.
После этого аргументы в духе "макросы усложняют язык" выглядят смешно. Вместо написания макроса на 5 строк всей экосистемой писали if err != nil, и продолжают писать.

Sign up to leave a comment.

Articles