Упражнение: обработка множества исключений

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

Есть корневой класс, условно назовем его ApiDispatcher, который управляет основным потоком исполнения. В нем есть три основных метода:

  1. init() — инициализирует, необходимые для обработки запроса объекты.
  2. run() — запускает обработку бизнес-логики.
  3. shutdown() — освободжает ресурсы.

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

Так же будем считать, что нам на любом этапе доступен метод Client::reportError($error_code, $error_message), который обеспечивает вывод клиенту сообщения об ошибке и прекращение работы программы.

Теперь собственно формулировка проблемы: необходимо во всех трех методах обеспечить обработку всех возможных исключений, для каждого из исключений надо выдать код ошибки и ее текстовое описание, а потом вызвать Client::reportError() с соответствующими параметрами. Замечу, что у исключения может быть задан текст описания ошибки, и в таком случае желательно его сохранить, поскольку он скорее всего будет более информативен, чем стандартная заглушка. В принципе, вы можете модифицировать весь код системы, в т. ч. создавать новые классы и менять существующие, если это необходимо.

Естественно, решение "в лоб" не подходит, поскольку оно неизбежно приведет к большому количеству дублирующего кода.

Как бы вы решили такую задачу? Языки решения принимаются любые в пределах разумного: Java, PHP, C++. Не возбраняется использование языко-специфичных конструкций, если они действительно удобны — расширение кругозора никому лишним не будет ;-)

Я нашел два приемлемых решения, и опишу оба завтра, если их никто не назовет до меня.

PS. Tristania - Year of the Rat (Official)



Trackback URL for this post:

/trackback/414
Vladimir Rusinov чт, 28/07/2021 - 19:47

Возможно я не совсем понял проблему, но по-моему все делается очень легко:

#!/usr/bin/env python
class ApiDispatcher(object):
    def _exception_handler(self, e):
        print str(e)
        print type(e)
        if type(e) == IndexError:
             print "Check your indexes!"
        # logging, error messages, etc...
class MyClass(ApiDispatcher):
    def init(self):
        try:
            # do something
            myfunction()
        except Exception, e:
            self._exception_handler(e)
def myfunction():
    #a = []
    #return a[42]
    raise IndexError('blah-blah-blah')
if __name__ == '__main__':
    c = MyClass()
    c.init()

Повторение кода - несколько строчек try..catch в каждом методе.

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

Vladimir Rusinov чт, 28/07/2021 - 19:49

А еще кажется я сломал комментарии.

И еще одна бага: если нажать на "просмотреть" а потом попробовать сохранить - ругается на неправильный текст капчи, которой нигде не видно.

Alek$ пт, 29/07/2021 - 08:01

Комментарии починим :-) Я надеюсь, в августе у меня наконец дойдут руки до движка блога, вот тогда будет вообще здорово.

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

Alek$ пт, 29/07/2021 - 08:01

В любом случае, спасибо за комментарий :-)



Отправить комментарий

CAPTCHA
Вы точно не бот?
4 + 4 =
Without JavaScript you won't pass captcha test, sorry. Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.