Пушыстый (_winnie) wrote,
Пушыстый
_winnie

exceptions

1. Относительно checked exceptions в Java (список разрешённых исключений в декларации метода):
у меня нет проблем с мего-списком исключений, такой список от непонимания кода и непонимания как транслировать исключения. И от того, что для своего исключения из 3-х строчек надо создать ещё один файл FooBarException в проекте.

Есть зато проблема когда библиотечный код вызывает мой. Я не могу прозрачно перекинуть свои исключения обратно в свой код. Типичные примеры:

1)container.forEach( мой код )
2)
class MyClass: extends LibraryInterface
{
@override
void execute() { мой код }
}


Вчера пришлось переписать такой forEach на for из-за того что он звал функцию которая звала функцию в которой добавилось IOException.

2. Моя точка зрения на жизнь с исключениями:
Часто хватает одно общее на всех исключение, единственное содержание которого - строка об ошибке. Ну и добавлять в правильных местах
catch(error_description)
  throw UniException("Save Game failed\n" + error_description)
---
catch(error_description)
  throw UniExceptioncan't load file " + FileName + '\n') + error_description


При этом можно выдать внятное сообщение об ошибке, где для каждой ошибки пишется почему она произошла. В культуре использования int как возвращаемого кода ошибки такое практически невозможно и не делается.
не могу загрузить уровень 'level1'
  не могу загрузить данные из level1/chunks.zip
    не могу распарсить файл 'data/chunk_03_07.xml'


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

С локализацией технической информации никто не заморачивается, так как пользователь-блондинка всё равно не сможет понять что делать, даже если информация на родном языке. Обычно есть просто кнопка "послать разработчику" или "позвать сына". Тем не менее, можно добавить LOC_ID в своё универсальное исключение.

3. Геймдевелоперы живут без исключений, они им не нужны, часто можно вместо throw показывать MessageBox с описанием и тут же делать ExitProcess. Тем не менее, стоит предусмотреть вложенную диагностику ошибок (см. выше пример с вложенной диагностикой при загрузке уровня). Для этого нужен макрос похожий на макрос для профайлера секций,
{
  SET_ERROR_CONTEXT("Loading level '%s'", level_name.c_str())
  ....
}

SET_ERROR_CONTEXT создаёт объект на стеке, в конструкторе и деструкторе которого создаются "логические скобки" для уточнения ошибки.

Читать сообщение в MessageBox "функция zlib.deflate вернула не ноль" мне бессмысленно. Если я разработчик, то хочу знать какой файл в паке битый, какое заклинание испортили дизайнеры. Если я пользователь, я хочу знать какой пак для маминой игрушки перекопировать с CD и вообще если я сисадмин а не программист, то я могу не знать что такое zlib.deflate. А если я увижу имя битого пака, это другое дело.

Проще использовать логи, но SET_ERROR_CONTEXT эффективней, если ошибки нет, он не делает flush каждой строчки в лог, и не надо разбираться в логе с миллионом [DEBUG], [INFO] без скобочной структуры.
Tags: c++, java, release, soft-dev
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 22 comments