TransWikia.com

Подход к обработке исключений c#

Stack Overflow на русском Asked on January 20, 2021

Вопрос больше ориентирован на архитектурный подход или рефакторинг. Например есть консольное приложение, где есть класс FileWorker работающий с файлами , экземпляр которого инициализируется в Programm.cs в точке входа (main) и идет дальнейшая работа с его методами. Правильно ли для обработки исключений блок конструкцию try catch размещать только в точке входа main, как говорится прокидывать при исключениях ошибки вверх, или все же try catch нужно вешать непосредственно внутри методов и классов? Хочется избежать перенагромаждения синтаксиса кавычек и т.д. -прийти к лаконичности. И также хотелось бы узнать как элегантно обрабатывать исключения асинхронных методов (asynh await), как прокидывать из них throw до основного потока?

2 Answers

Это все хорошо, но как сделать код более читаемым, если не прокидывать наверх Exceptions. Хочется ,чтобы обработчик ошибок был один на клиентской вызывающей стороне (main) в точке входа, где инициализируются обьекты и идет работа с ними, не хочется под их капотом нагромождать блоки try catch , дабы избежать синтаксические громоходы-болячки в духе языка Flutter :) -где проблемы с символами "{}", делает код менее читаемым.

Answered by user344622 on January 20, 2021

Не всегда и не все исключения надо пробрасывать "наверх". Например, вы работаете с каналами связи - качаете файл через сеть, или парсите сайт или ещё что-то такое делаете и у вас вышла ошибка - связь оборвалась/вышел таймаут/антивирус заблокировал файл на проверку. Хорошо ли в этом случае бросать исключение на самый верх в main? Конечно же нет! Есть ошибки, после которых вы должны поймать исключение примерно в том месте, где оно выбросилось (или чуть выше по коду - смотря как у вас сделан рефакторинг) и сделать что-то из следующего (а может и несколько пунктов сразу):

  • Сделать паузу и попробовать выполнить последнюю операцию ещё раз (и так несколько раз в цикле)
  • Положить обрабатываемый элемент обратно в очередь обработки (у вас же есть очередь обработки?), увеличив у этого элемента число совершённых попыток и пометив, когда была последняя попытка
  • Отослать письмо на заранее прописанные адреса с текстом "Шеф, все пропало, гипс снимают, клиент уезжает!"
  • Почистить место на диске, рестартовать сервис, перегрузить модем...

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

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

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

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

Answered by CrazyElf on January 20, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP