Клуб API Карт

Неизвестная ошибка в Opera

Пост в архиве.

 

Здравствуйте, в проекте периодически вываливается непонятная ошибка, которая возникает не систематично (где-то 2 раза из 3). Вроде бы, проблема не в моём коде (источник точно ваш, если верить консоли ошибок). Как бороться, не знаю, решил написать сюда. Надеюсь, кто-нибудь сможет помочь. Как воспроизвести: перейти по адресу http://kudainfo.ru/ecomobile.html, выбрать в качестве интервала 1 месяц (или сразу перейти по адресу http://kudainfo.ru/ecomobile.html?month).

 

Проблема проявляется в Opera 11 и 12, в Firefox проблемы нет, но там зато в целом всё медленнее грузится по ощущениям, и геоданные от браузера актуализируются как бы не сразу, приходится ждать секунд 10.

 

Так же хочется отметить, что на интервалах 1 и 2 недели сейчас ошибки нет (но иногда выскакивала и там). Такое ощущение, что это как-то связано с общим количеством точек (хотя оно явно не запредельное, да и на аналогичной карте на сайте http://www.infoeco.ru/ecomobile/index.php?id=34 никаких косяков нет, даже несмотря на то, что у них добавление как-то странно сделано, часть точек добавляется повторно на карту).

 

Алгоритм у меня такой - в айфрейм грузится PHP скрипт из того же домена, который открывает сторонний ресурс (выкачивает данные), и внедряет в нужное место JS код, который, в свою очередь, добавляет объекты с данными точек в массив, определённый в основном окне (parent). В конце функции, повешенной на onload, инициализируется карта (по инструкции стандартно), а в колбэке (функции, которая расставляет объекты), уже берутся данные из того массива. Я вот чего понять не могу - неужели проблема в том, что айфрейм не успевает прогрузиться (или JS код в нём отработать)? Почему тогда текст ошибки такой странный? Всё же, дело скорее всего не в этом, потому что там цикл for по длине массива с данными, и если вдруг массив не заполнился, то точки просто не добавятся. Но вылет карты?..

 

28 комментариев

 

Алгоритм у меня такой - в айфрейм грузится PHP скрипт из того же домена, который открывает сторонний ресурс (выкачивает данные), и внедряет в нужное место JS код, который, в свою очередь, добавляет объекты с данными точек в массив, определённый в основном окне (parent). В конце функции, повешенной на onload, инициализируется карта (по инструкции стандартно), а в колбэке (функции, которая расставляет объекты), уже берутся данные из того массива. 

 

Непонятно зачем это нужно и как это отлаживать.

Александр Попов
27 января 2016, 23:58

Как зачем? По-моему, вполне себе очевидный способ обойти Same Origin Policy. XHR иначе не пройдёт. Есть конечно всякие фичи с выставлением специальных заголовков, но сайт, с которого я получаю данные, контролируется не мной.

 

Как отлаживать - так что тут непонятного, если падает именно ваш API. Я могу текст ошибки даже привести, только я думаю, лучше в режиме дебага это делать... 

 

с которого я получаю данные, контролируется не мной.

А сайт с которого вы получаете данные знает о том что вы получаете с него данные?

 

 

Как отлаживать - так что тут непонятного, если падает именно ваш API. Я могу текст ошибки даже привести, только я думаю, лучше в режиме дебага это делать... 

Если тут все так очевидно – зачем тогда спрашивать?

Если ошибка только у вас, почему "падает именно АПИ"?

Ваша страница в моей опере не открывается совсем.

https://yadi.sk/d/Yva7R5u5W729C

 

У вас и АПИ то не загружается.

Вываливается на этой проверке

   function init() {

      if (detectIE()) return

Александр Попов
27 января 2016, 23:58

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

Ошибка, я думаю, у всех.

 Вываливается на этой проверке

Очень странно это... У вас Opera под Mac, я вижу, под маком я ни разу не тестировал... Как и в новых Операх. Но что падает - странно. В IE работать не должно, там какие-то серьёзные трудности были (не с картой), для чего и стоит проверка на браузер на старте.

 

Вообще код функции detectIE() Вы сами можете глянуть - падать там нечему, а если функция вернула true, значит у Вас в юзер-агенте строка MSIE и число меньшее 9 после неё... Если так, что ж я могу поделать. Речь вообще шла именно про Opera под Windows, и не выше 12 версии...

 

Переключил в режим дебага - проблема исчезла. Совсем. Как Вы это прокомментируете? Валится в релизе, причём не всегда (процентов 80-90 запусков), а в дебаге нет...

Александр Попов
27 января 2016, 23:58

Вот текст ошибки:

Error thrown at line 1, column 1140904 in (e) in http://api-maps.yandex.ru/2.0.38/release/combine.xml?modules=4(4q.p4)$q-b$j$)8k.n4R4X4V4U7N7O477S44494$$(5y$_-i$*5A43464T404Y9p419u9I8d7Q$Z7*7!4!8p5L5H9t3O9r3H6B5D4.5Q3U6F7...

K1n011_1f2m1F&jsonp_prefix=ymaps2_0_38:
this._ly.hasOwnProperty(e)?this._ly[e]++:this._ly[e]=1,this._pd(n,t),n=this.types[e];
called from line 1, column 384472 in (e, t) in http://api-maps.yandex.ru/2.0.38/release/combine.xml?modules=4(4q.p4)$q-b$j$)8k.n4R4X4V4U7N7O477S44494$$(5y$_-i$*5A43464T404Y9p419u9I8d7Q$Z7*7!4!8p5L5H9t3O9r3H6B5D4.5Q3U6F7(7j7,7q7)7z5K-s5V51-D-C5X538-5Y-u-y-A-v-x-B6_6$6!6*-9-4-(-q-55B5.5d.f.h.l.g.k.r.t.o9L8o8g8a$Q8n9...

1j2D2I0T3b1)1G1o1D0(281a3m1z1O!s._0y2*2Z1K6z7e3q-k202H1Y2J162l0x112K1n011_1f2m1F&jsonp_prefix=ymaps2_0_38:
t.isImmediatePropagationStopped()||this.noPriorityManager.fire(e,t)
 

ну так включите режим debug то.

какой толк от указателя на первую строку обфусцированного кода?

 

Александр Попов
27 января 2016, 23:58

Включил, отписал выше. Самое удивительное, что в дебаге проблемы нет. 

Сейчас ошибка в релизе только в режиме "2 недели" (до этого в режиме "1 месяц" тоже ошибка была).

У меня такое ощущение, что дело в обфускаторе. А поскольку пустота массива явно не причина падения (значит, дело не в том, что минифицированный вариант грузится быстрее), то остаётся только сам обфускатор, который где-то что-то портит... Кстати, зачем Вы вообще его юзаете, если для всех желающих есть дебаг режим? Только грузит процессор дополнительно. Минифицировать можно и просто сокращая имена переменных и убирая комментарии и переносы строк :)

Вы выше писали, что у вас в апи передается массив объектов, который на момент передачи может быть не заполнен. Не могли бы вы поставить проверку и посмотреть, инициализирован ли весь массив точек на момент отрисовки точек на карте.

Добавление точки с некорректными координатами вполне может спровоцировать такие ошибки.

Александр Попов
27 января 2016, 23:58

Спасибо, попробую отладочную печать организовать сейчас.

Вообще непонятно всё равно, почему с дебагом всё в порядке. При том, что айфрейм вообще тот же без изменений (и код в нём такой же). Неужели чисто задержка загрузки API спасает?

Да, апи в дебаге весит больше - грузится дольше, в результате ваш файл с данными успевает подготовиться

Александр Попов
27 января 2016, 23:58

Но в режиме "1 месяц" точек примерно вдвое больше, соответственно, "перегонка" их в массив в родительском фрейме тоже должна занимать больше времени, но там вылета нет... Надо сейчас смотреть, что с точками. Может, какие-то точки есть плохие... Только тогда бы оно вообще не работало, и в дебаге тоже.

В смысле вылета нет? Мы баги ловим как раз на выдаче "месяц"

Александр Попов
27 января 2016, 23:58

А я только на "2 недели". Вот забавно

kudainfo.ru/ecomobile2.html - тут дебаг включён. есть вылет?

Александр Попов
27 января 2016, 23:58

Перечитал сейчас внимательно код. Сначало было подумал, что глупая ошибка с неправильным порядком вызова: src айфрейма задаётся следующей строкой после вызова createMap(), и всё это повешено на таймаут в 400 мс для улучшения впечатлений от загрузки. Думаю, нелепость же - данные начинают загружаться позже, чем вызывается создание карты. Потом понял, что не такая уж нелепость: функция addMarks(), добавляющая метки, вызывается из айфрейма (гарантируя готовность данных, но, правда, не гарнтируя готовность API). И проблема наверное могла быть в том, что на момент, когда интерпертатор начинает её исполнять, ещё не до конца готова карта и её коллекции, куда метки добавляются. Но ведь когда меток больше, копирование их данных в родительский фрейм, опять же, длится дольше (а создание карты и метки с центром занимает примерно одинаковое время во всех режимах), и тогда выглядит не логичным, что как раз в режимах "2 недели" и "месяц" идёт сбой. Короче, я окончательно запутался...

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

Александр Попов
27 января 2016, 23:58

Алерты нельзя, они останавливают поток (и многие ошибки разрешаются при этом сами на то время, пока они стоят). В таких вещах только console.log() =)

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

Александр Попов
27 января 2016, 23:58

Ну вообще жесть какая-то. Поставил в этот скрипт sleep(1) для надёжности (чтобы притормозить приход данных), так что же? Карта создаётся, метка с домиком появляется, и висит секунду-полторы. Потом данные приходят, карта перемещается (меняет зум, трудно сказать что это, в этот момент серая подложка), и идёт вылет. То есть дело вроде бы не во времени, выходит.

давайте так - поставьте единственную проверку - перед добавлением меток на карту выведите в консоль координаты всех меток, которые добавляются. И все.

Александр Попов
27 января 2016, 23:58

Всё, я поймал проблему вроде. Хотя звучит самоуверенно довольно, но вроде похоже на правду. И похоже, проблема на вашей стороне.

 

Смотрите, где был вылет - в момент зума.

Вот код моей функции:

 

for (var i = 0; i < marks.length; i++) {  //для каждой остановки

var p = new ymaps.Placemark(marks[i].coords.reverse(), { iconContent: i+1,
balloonContent: marks[i].baloon.content,
balloonContentHeader: marks[i].baloon.header,
  balloonContentFooter: marks[i].baloon.footer }, {}) //создали точку


myMap.geoObjects.add(p); //добавили (ну или запустили её добавление, возможно, процесс не мгновенный)


if (myCircle.contains(p)) {
     p.options.set({
        preset: 'twirl#greenStretchyIcon',
     });
     p.properties.set({
        walk: 1,
     });
     count++


     var d = myMap.options.get('projection').getCoordSystem().getDistance(p.geometry.getCoordinates(), myCircle.geometry.getCoordinates())
     a.push({obj: p, index: i, distance: d})
} else {
     p.options.set({
        preset: 'twirl#blueStretchyIcon',
     });
}
  }

if (count>0) { 

на  этот момент объекты добавлены, и дальше идёт некоторая логика, не связанная с картой...

attachHandlers() //ставим обработчики

//myMap.setZoom(14, {})

я закомментировал эту строку, и вылетать перестало!

...ещё немножко вспомогательной логики

 

И по картинке видно, что слетает именно в момент смены масштаба. Метки ещё не появились на экране, серый фон, крупно нужный участок (зум сработал), и мёртвая карта. Так значит проблемы с зуммированием, если не подождать достаточно времени после добавления объектов, мне такой вариант видится самым вероятным... 

 

Александр Попов
27 января 2016, 23:58

А ещё если поставить таймаут (даже 10 мс) - проблемы нет... Хех, жалко. Я же чтобы определить, надо ли делать зуммирование, должен узнать расстояния. Делаю я это с помощью вашего API, для этого точки должны быть добавлены... Зуммировать до их добавления я никак не могу, потому что ещё не известно, есть ли точки в радиусе. Печаль вообще

Наши тестировщики ловят баг, так как они в питере. А я в москве не могу поймать баг. Вы можете поставить метку геолокации принудительно так, чтобы в круг попадали метки?

Александр Попов
27 января 2016, 23:58

Могу попробовать сделать копию файла и захардкодить координаты, ОК. kudainfo.ru/ecomobile-test.html

Вроде нашли, в чем баг (какая-то странная гонка событий). Починим в будущих релизах. Спасибо за репорт)

Если не сложно - не грохайте пока эту страничку

Спасибо за ресерч) Будем изучать, что это такое

Александр Попов
27 января 2016, 23:58

Не за что)

Александр Попов
27 января 2016, 23:58

Всё, перехожу на дебаг. На мой взгляд это изящнее, чем таймауты пихать... Да и понадёжней. Теперь старая версия доступна по адресу kudainfo.ru/ecomobile-old.html, а версия с дебагом теперь на основном адресе.

Александр Попов
27 января 2016, 23:58

Ещё такой странный момент - раньше иногда падало при переключении через список (location.search = '...'), а при нажатии F5 иногда загружалось нормально. Ну как иногда, в половине случаев. А сейчас наоборот... Через список вроде грузит и расставляет точки, а если нажать F5 - мёртвая карта. При этом в Firefox тестил так и сяк минут 5 сегодня утром, не завсила ни разу вот так. Это именно Opera, только я не понимаю, что это :)

Сейчас кстати не работает только режим "2 недели", что характерно. Я вот тут подумал - там же данные всё время меняются (с течением времени). Может, проблема в данных? Могут какие-то метки так вешать?