— Здравствуй, дружок. Хочешь, я расскажу тебе сказку? }:-]
— Конечно, дяденька, а какую? *_*
— Я расскажу тебе как делают детей ^_^'
— ого, как интересно! @_@
— Так вот, слушай. Дети появляются вследствие долгого и изнуряющего процесса разной степени нецензурности. Сейчас я поведаю тебе как появился на свет мой сын %-)
— А вы меня с ним познакомите? *о*
— Не торопи события. Обо всём по порядку. Однажды я наваял такой код:
— Не важно, главное, тут другое, а именно то, что только Опера и Мозилла в консоли ошибок указали на вторую строку скрипта. Хром указал на четвёрную, а Ишак вообще на третюю .-.
— Ну и что с того? ._.
— А то, что использование таких конструкций перепосылки исключений в общем случае приводит к тому, что исключения теряют свои координаты и становятся совершенно бесполезными при отладке. Мы знаем, что произошла ошибка, даже знаем какая, но только методом научного тыка можем установить где она произошла. Кроме того, в некоторых отладчиках есть полезная функция перехода в режим пошаговой отладки в случае возникновения ошибки… Догадайся, в каком месте произойдёт остановка исполнения т_т
— Тогда надо не делать так и всё будет хорошо! \(^_^)/
— Хех, если бы всё было так просто… К сожалению во всех популярных фреймворках встречаются подобные выкрутасы, причём во многих случаях ошибки просто сглатываются :-\
— Так не используйте их и все дела! =)
— Пхах! Наивный маленький мальчик! Это невозможно… по разным причинам… =(
— Почему? А что ещё остаётся-то? о0'
— Ну, я просто пропатчил используемый нами фреймворк, вычистив все перехваты ошибок нашего приложения, правда это слегка нарушило его api =_=
— Вау, а что вы там такого наворотили-то? 0_0
— Ну вот, лови пример:
— Это функция итерирования из prototypeJS. Видно его разработчики совсем не занимались отладкой скриптов в браузерах отличных огнелиса, так как реализовали прерывание цилка именно таким образом. Не буду утомлять тебя яваскриптом — скажу лишь, что я вырезал try-catch, а во все итераторы прописал передачу дополнительного параметра, возвращение которого прерывает итерирование ^_^
— Как всё хорошо закончилось! :-)
— Нет, только началось… Не всегда итерирование можно просто взять и вырезать, ибо иногда требуется выполнить какой-то небезопасный код так, чтобы он не прервал выполнение нашего. Вот, лови пример из jQuery:
— Ну, тут я стащил немного семени Дина Эдвардса ( dean.edwards.name/weblog/2009/03/callbacks-vs-events ) и породил враппер, который выполняет некоторый кусок кода безопасно от остального, при этом ни коим образом не перехватывая исключения, а отдавая их на попечение отладчику В-]
— Чего-чего? :-О
— Грубо говоря, последний код можно переписать следующим образом, позвав на помощь моего сына по имени FThread:
— М… дружок, лучше я оставлю вас на едине — он сам о себе всё красноречиво расскажет ;-)
— Конечно, дяденька, а какую? *_*
— Я расскажу тебе как делают детей ^_^'
— ого, как интересно! @_@
— Так вот, слушай. Дети появляются вследствие долгого и изнуряющего процесса разной степени нецензурности. Сейчас я поведаю тебе как появился на свет мой сын %-)
— А вы меня с ним познакомите? *о*
— Не торопи события. Обо всём по порядку. Однажды я наваял такой код:
- try {
- throw new Error
- } catch( e ){
- if( e != false ) throw e
- }
— А что он делает? о_0— Не важно, главное, тут другое, а именно то, что только Опера и Мозилла в консоли ошибок указали на вторую строку скрипта. Хром указал на четвёрную, а Ишак вообще на третюю .-.
— Ну и что с того? ._.
— А то, что использование таких конструкций перепосылки исключений в общем случае приводит к тому, что исключения теряют свои координаты и становятся совершенно бесполезными при отладке. Мы знаем, что произошла ошибка, даже знаем какая, но только методом научного тыка можем установить где она произошла. Кроме того, в некоторых отладчиках есть полезная функция перехода в режим пошаговой отладки в случае возникновения ошибки… Догадайся, в каком месте произойдёт остановка исполнения т_т
— Тогда надо не делать так и всё будет хорошо! \(^_^)/
— Хех, если бы всё было так просто… К сожалению во всех популярных фреймворках встречаются подобные выкрутасы, причём во многих случаях ошибки просто сглатываются :-\
— Так не используйте их и все дела! =)
— Пхах! Наивный маленький мальчик! Это невозможно… по разным причинам… =(
— Почему? А что ещё остаётся-то? о0'
— Ну, я просто пропатчил используемый нами фреймворк, вычистив все перехваты ошибок нашего приложения, правда это слегка нарушило его api =_=
— Вау, а что вы там такого наворотили-то? 0_0
— Ну вот, лови пример:
- each: function(iterator, context) {
- var index = 0;
- try {
- this._each(function(value) {
- iterator.call(context, value, index++);
- });
- } catch (e) {
- if (e != $break) throw e;
- }
- return this;
- },
— Что это? +_+'— Это функция итерирования из prototypeJS. Видно его разработчики совсем не занимались отладкой скриптов в браузерах отличных огнелиса, так как реализовали прерывание цилка именно таким образом. Не буду утомлять тебя яваскриптом — скажу лишь, что я вырезал try-catch, а во все итераторы прописал передачу дополнительного параметра, возвращение которого прерывает итерирование ^_^
— Как всё хорошо закончилось! :-)
— Нет, только началось… Не всегда итерирование можно просто взять и вырезать, ибо иногда требуется выполнить какой-то небезопасный код так, чтобы он не прервал выполнение нашего. Вот, лови пример из jQuery:
- // Trigger an inline bound script
- try {
- if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
- if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
- event.result = false;
- }
- }
- // prevent IE from throwing an error for some elements with some event types, see #3533
- } catch (e) {}
— Ой, а как же быть тогда-то? о_о'— Ну, тут я стащил немного семени Дина Эдвардса ( dean.edwards.name/weblog/2009/03/callbacks-vs-events ) и породил враппер, который выполняет некоторый кусок кода безопасно от остального, при этом ни коим образом не перехватывая исключения, а отдавая их на попечение отладчику В-]
— Чего-чего? :-О
— Грубо говоря, последний код можно переписать следующим образом, позвав на помощь моего сына по имени FThread:
- // Trigger an inline bound script
- // prevent IE from throwing an error for some elements with some event types, see #3533
- FThread( function(){
- if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
- if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
- event.result = false;
- }
- }
- }).call( this )
— А если не так грубо? :-[— М… дружок, лучше я оставлю вас на едине — он сам о себе всё красноречиво расскажет ;-)
var FThread= new function(){<br><br>Version: 4<br>Description: 'creates a wrapper for function that allows you to not be afraid of exceptions in'<br>License: 'public domain'<br> <br>Implementation:<br><br>var scripts= document.getElementsByTagName( 'script' )<br>var script= scripts[ scripts.length - 1 ]<br>var starter= document.createElement( 'button' )<br>starter.id= 'thread starter'<br>starter.style.display= 'none'<br>script.parentNode.insertBefore( starter, script )<br><br>var FThread= function( proc ){<br> var thread= function( ){<br> var res, self= this, args= arguments<br> starter.onclick= function( ev ){<br> ( ev || event ).cancelBubble= true<br> starter.onclick= null<br> res= thread.proc.apply( self, args )<br> }<br> starter.click()<br> return res<br> }<br> thread.proc= proc<br> return thread<br>}<br><br><br>Export: return FThread<br><br>Usage:<br><br>var inverse= FThread(function( a ){<br> if( a === -1 ) (void 0)()<br> if( a === 0 ) throw Error( 'division by zero' )<br> return 1/a<br>})<br>alert([ inverse( -1 ), inverse( 0 ), inverse( 1 ) ])<br>// alerts ",,1" and two exceptions in console log<br><br>}