Известно, что AS3 строже относится к ошибкам. Мелких ошибок тут нет: любое исключение может остановить работу приложения на любом этапе. Как пишет Dan: "... нам нужно исправлять эту маленькую кривость, которая превратилась в критическую ошибку: вставлять if или try..."
Также известно, что в ActionScript 3 ( Flash Player 9 / AVM2) блок try...catch...finally намного производительнее, чем в ActionScript 2.
try...catch...finally
В связи с этим пришла мне в голову крамольная мысль заключить в этот блок все приложение:
try { creationCompleteHandler(); } catch (e: Error) { trace("Вы ошибаетесь, мой друг. " + e); }
Это пример для Flash. Вопросы:
Update 1: Но должен быть способ продолжить работу после непойманой ошибки!
Update 2: Идем к решению прямым путем: в Adobe JIRA голосуем за исправление этого бага.
Update 3: Илья Панин в комментариях дает ссылку на вот такое решение для Flex.
Всё приложение не получится. Пример: try { button.addEventListener(MouseEvent.CLICK, handleClick); } catch (e:Error) { trace("Вы ошибаетесь, мой друг! " + e); }
try { button.addEventListener(MouseEvent.CLICK, handleClick); } catch (e:Error) { trace("Вы ошибаетесь, мой друг! " + e); }
"Ошибкоустойчивость" тут приобретёт только одна строчка - добавление лисенера.
Внутри функции handleClick у нас всё равно может родится unhandled exception, посколько действие try туда не распространяется.
"Геморройный" способ: вставлять try...catch в каждую функцию. Или хотя бы в каждый обработчик события. Но придётся хорошо порабоать руками (или скриптик какой-нить написать).
"Правильный" способ (как оно и подразумевалось): добавлять try...catch только там, где действительно может есть риск возникновения эксешна. Хотя это это ещё сложнее, ибо придётся ещё головой думать, в отличии от предыдущего варианта, где требуется чисто механическая работа.
А чего тут думать-то? Голосовать надо!
Вот здесь: http://bugs.adobe.com/jira/browse/FP-444
http://www.docsultant.com/site2/articles/flex_internals.html#uerror
// за линку спасибо Глабуде Олегу и чату
в джаве например try ... catch .. finally в каждом методе, это нормальная практика.
вот отловить "такую" ошибку мы так и не смогли.
http://groups.google.com/group/ruFlash/browse_thread/thread/5b395b08549551b8/458398c9626a65db
все точки входа в апп - конструктор главного спрайта + лисенеры, подписаные на евенты + колбеки с сервера. Если так уж хочется отловить все ексепшены, то можна написать класс похожий на АС2 Delegate подписыватся на евенты и колбеки через него, а в нем поставить try catch блок. Этого вполне хватит, чтоб в случае ексепшена залогать его и показать модальное окно типа "случилась херня, рефрешните страницу".
Mokus, на мой взгляд возможность отлавливать все ошибки единым трайкэтч, это бред. а вот возможность отловить любую ошибку - это нужда.
Во многих скриптовых языках есть возможность установить глобальный отловщик ошибок. Для решения такой проблемы в AS3 могу порекомендовать такое решение:
1. В "самостоятельных" или "завершенных" до нужной степени местах пишем:
try { ... } catch (error:Error) { Exception.handle(this, error); }
и не забываем про события-ошибки: function on_error(event:ErrorEvent):void { Exception.handleEvent(this, event); } ...
function on_error(event:ErrorEvent):void { Exception.handleEvent(this, event); } ...
2. А у Exception сделать метод setHandler( handler:IExceptionHandler ), в котором указываем кто именно будет принимать и обрабатывать ошибки, возможно даже и выводить alert-ы...
а Proxy заюзать для отлова никак не получится?
override flash_proxy function getProperty(name:*):* ...
2 BlooDHounD: возможность отловить все ексепшены - нужда. Насчет примера, что ты описал выше - сочувствую.
Отлавливать все ексепшены единственным трай кетчетм- бред, но никто этого не предлагал.
Отлавливать и логать все ексепшены, которые не отловили на этапе тестирования перед релизом - правило хорошего тона. Тогда твои юзеры вместо того, чтоб матерится когда у них апп вдруг перестала работать (у них не дебаг плеера и ексепшены не показывает) увидят окошко "рефрешните апп" и, возможно, простят тупых девелоперов, что не половили все ексепшены. А Ты получиш лог, на основе которого раздуплишся, где ты напорол и поставиш очередной трай-кетч.
Mokus, ну блин :) если не отловил все баги, то это кривые руки разработчика.
Zzloba, причём тут прокси? вы с какой планеты?
>Mokus, ну блин :) если не отловил все баги, то это кривые руки разработчика.
Mokus прав. Кривые или нет, это уже другая тема. (они у всех бывают кривыми время от времени, если хотите знать моё мнение. у вас ни разу не выпадало ошибок в ваших любимых программах? я вот что-то не припоминаю ни одной идеальной).
На мой взгляд, глобальный обработчик не имеет смысла. Если он или нет, нормальное течение программы прервано, программа попала в некорректное (неизвестное) состояние, и вернуть в нормальное состояние можно только переинициализацией.
Не проще ли приучить пользователей просто перегружать приложение во время ошибки? И без сообщения об этом?
Добавили бы обязательный 'throws' для определения метода, как в яве, вообще бы сказка была... Может предложить адобовцам?
Ухх, сколько всего нового я узнал! Спасибо, друзья!
2 Arsu: окно окном, а залогать баг надо. для того и обработчик.
2 BlooDHounD: ну... я думал почти так как ты пока не начал писать ммо.
throws не получится добавить для подписки на евенты. так же как в жаве throws ниче не решает когда вызываеш метод черезрефлекшены. кроме того throws имхо параноя. я рад. что его в ас нету.
Mokus, бугага :) а какая разница что писать?
Иногда приложение падает прямо при старте - перезапускай не перезапускай :) Причём на машине разработчика-то всё работает прекрасно :)
2 BlooDHounD: бугага, что ты такое спрашиваеш.
Mokus, мне просто непонятно, как зависит мышление, от того пишешь ты ММО, t4t, или cms.
2 BlooDHounD: мышление не зависит. но мышление и не выкидывает ексепшены.
Mokus, ну тогда расшифруй:
2 BlooDHounD: 1. Предотвратить все баги/ексепшены на этапе девелопмента не получается (по крайней мере у меня и всех девов, что я знаю) - все равно какието словит тестер (или девелопер когда тестает). 2. При разработке ммо некоторые баги/ексепшены репродюсятся только когда на локации больше Х (например больше 20) чаров и то в определенных условиях. Такие баги тестеры не словят - разве что есть возможность посадить Х тестеров.
а в двух словах: в ммо очень большой процент исключительных ситуаций, которые ты (девелопер) не сможеш воспроизвести.
Mokus, мдя ... сочувствую. тоесть у Вы считаете, что пункт "первый" не разработка? по второму Вы считаете, что плавающих багов не бывает в других приложениях? я 4 года занимаюсь ММО, я думаю, что я не тот, кому нужно рассказывать про 20 чаров :)
Можно: a href target blockquote strike strong em code pre small img width height border
code