Что нового

Война с ошибкой "Unexpected Error" в FF

bescom

Новичок
Сообщения
61
Репутация
0
Преамбула: В одном из моих AutoIT скриптов FF ходит со страницы на страницу, переходя по ссылкам (по разным сайтам). Ходит, используя в качестве прокси сеть TOR.
Сама проблема: Видимо, некоторые сервера не всегда корректно передают данные, из-за чего иногда появляется следующее окошко с неопознанной ошибкой:
c7eb815e0292.jpg

Попытки отучить браузер выводить это окно не увенчались успехом. Искал в about:config, чтобы выключить вывод ошибки - безуспешно. На Сёрче предположили, что это не браузер выводит сообщение, а JS выполняет <script>alert()</script>. На форуме поддержки пользователей Firefox вообще скромно промолчали.

Решил пойти другим путем: при возникновении этого окошка закрывать его, проверяя присутствие из скрипта, тем более что закрывается оно простым нажатием Enter, а браузер после закрытия нормально продолжает работу. Но и тут столкнулся с проблемами. Перечислю варианты, которые я перепробовал, по порядку:

1. Самый простой способ - проверить наличие окна с определенным текстом и отправить Enter.
Код:
Func UE() ; Закрываем ошибку "Unexpected Error"
   If WinExists("", "Unexpected Error") Then
	  WinActivate("Mozilla Firefox")
	  Send("{ENTER}")
   EndIf
EndFunc
Получается, но один раз из двадцати. Не пойдет. Кстати отмечу, что AutuIT Window Info это окно не видит.

2. Открываю утилиту Inspect и изучаю окно. Результат:
How found: Mouse move (638,386)
hwnd=0x000505C8 32bit class="MozillaWindowClass" style=0x17CF0000 ex=0x100
BoundingRectangle: {l:598 t:382 r:683 b:396}
ProcessId: 3436
ControlType: UIA_EditControlTypeId (0xC354)
LocalizedControlType: "edit"
Name: "Unexpected Error"
AccessKey: ""
HasKeyboardFocus: false
IsKeyboardFocusable: false
IsEnabled: true
HelpText: ""
IsPassword: false
IsOffscreen: false
ProviderDescription: "[pid:3436,hwnd:0x0 Main(parent link):Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]"
Value.IsReadOnly: false
Value.Value: ""
LegacyIAccessible.ChildId: 0
LegacyIAccessible.DefaultAction: ""
LegacyIAccessible.Description: ""
LegacyIAccessible.Help: ""
LegacyIAccessible.KeyboardShortcut: ""
LegacyIAccessible.Name: "Unexpected Error"
LegacyIAccessible.Role: редактируемый текст (0x2A)
LegacyIAccessible.State: обычный (0x0)
LegacyIAccessible.Value: ""
IsDockPatternAvailable: false
IsExpandCollapsePatternAvailable: false
IsGridItemPatternAvailable: false
IsGridPatternAvailable: false
IsInvokePatternAvailable: false
IsLegacyIAccessiblePatternAvailable: true
IsMultipleViewPatternAvailable: false
IsRangeValuePatternAvailable: false
IsScrollPatternAvailable: false
IsScrollItemPatternAvailable: false
IsSelectionItemPatternAvailable: false
IsSelectionPatternAvailable: false
IsTablePatternAvailable: false
IsTableItemPatternAvailable: false
IsTextPatternAvailable: false
IsTogglePatternAvailable: false
IsTransformPatternAvailable: false
IsValuePatternAvailable: true
IsWindowPatternAvailable: false
IsItemContainerPatternAvailable: false
IsVirtualizedItemPatternAvailable: false
IsSynchronizedInputPatternAvailable: false
FirstChild: [null]
LastChild: [null]
Next: [null]
Previous: [null]
Other Props: Object has no additional properties
Children: Container has no children
Ancestors: "" text
""
""
""
"Программа Бродяга | - Mozilla Firefox" window
"Рабочий стол" pane
[ No Parent ]
Вроде бы можно ухватить окошко по свойству Name с помощью библиотеки UIAutomate.au3. Пишу функцию:
Код:
#include "UIAutomate.au3"

Func UE()
     Opt("WinTitleMatchMode", 2)
   Do
	   $oParent = _UIA_GetElementFromHandle(WinActivate("Mozilla Firefox"))
	   Sleep(30)
   Until IsObj($oParent)

   While 1
	   $aAll = _UIA_FindAllElements($oParent, "Name", "Unexpected Error")
	   If Not IsArray($aAll) Then
		 Sleep(30)
		 ExitLoop
	   EndIf

	  WinActivate("Mozilla Firefox")
	  Send("{ENTER}")
	  ExitLoop
   WEnd
EndFunc
Вопреки ожиданиям, окошко не отлавливается. Функция или срабатывает ложно, или не видит его.

3. Ну его нафиг, попробую, не умничая, проверить на наличие пикселей с определенными цветами. То есть, у окошка 6 цветов, и при наличии всех - отправлять Enter.
Код:
Func UE()
   $pic=0
   $color1="F2F2F2"
   $color2="D4D0C8"
   $color3="FFFFFF"
   $color4="000000"
   $color5="808080"
   $color6="E6E6E6"

$x2=@DesktopWidth
$y2=@DesktopHeight
$var1=Pixelsearch(0,0,$x2,$y2, $color1,5, 2)
   if not @error then
	  $pic=$pic+1
   EndIf
$var2=Pixelsearch(0,0,$x2,$y2, $color2,5, 2)
   if not @error then
	  $pic=$pic+1
   EndIf
$var3=Pixelsearch(0,0,$x2,$y2, $color3,5, 2)
   if not @error then
	  $pic=$pic+1
   EndIf
$var4=Pixelsearch(0,0,$x2,$y2, $color4,5, 2)
   if not @error then
	  $pic=$pic+1
   EndIf
$var5=Pixelsearch(0,0,$x2,$y2, $color5,5, 2)
   if not @error then
	  $pic=$pic+1
   EndIf
$var6=Pixelsearch(0,0,$x2,$y2, $color6,5, 2)
   if not @error then
	  $pic=$pic+1
   EndIf

if $pic=6 then
   WinActivate("Mozilla Firefox")
   Send("{ENTER}")
EndIf
EndFunc
Фиг, не работает. Точнее, постоянные ложные срабатывания, когда нет вредного окошка.

4. Может, попробовать на наличие цвета затемнения?
Код:
Func UE()
   $pic=0
   $color="949494"
$x2=@DesktopWidth
$y2=@DesktopHeight
$var7=Pixelsearch(0,0,$x2,$y2, $color,5)
   if not @error then
      WinActivate("Mozilla Firefox")
      Send("{ENTER}")
   EndIf
EndFunc
Ничего подобного, функция не видит окно...

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

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
AutoIT Window Info это окно не видит
Значит первый способ не поможет - окно вы не найдёте.

окошко не отлавливается
Мы вроде с вами выяснили, что функции, использующие метод FindAll, на вашей конфигурации не работают. Попробуйте через FindFirst по аналогии с Ответ #51

В пунктах 3 и 4 цвет нужно задавать не строкой, а числом
Код:
$color=0x949494
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Может это окошко - элемент разметки с <button> OK?
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
InnI [?]
В пунктах 3 и 4 цвет нужно задавать не строкой, а числом
Вот стоит некоторым узнать, что все переменные имеют тип Variant, как они начинают считать, что и данные тоже можно использовать, как угодно... Это я про себя, конечно же...
Вариант 3 и 4 - собственно, одно и то же. После объединения этих вариантов и правки переменных способ заработал, только пришлось добавить цветов до десятка (добавил из муара затемнения), иначе были ложные срабатывания из-за того, что в любом градиенте серого находились все указанные цвета.

Попробуйте через FindFirst по аналогии с Ответ #51
А вот с этим возникли проблемы. Честно признаюсь - я не всё там понимаю, поэтому мой вариант не заработал:

Код:
Func UE() ; Закрываем ошибку "Unexpected Error"
     Opt("WinTitleMatchMode", 2)
   Do
	   $oParent = _UIA_GetElementFromHandle(WinActivate("Mozilla Firefox"))
	   Sleep(30)
   Until IsObj($oParent)

   While 1
	  $pCnd = _UIA_CreatePropertyCondition("Name", "Unexpected Error")
	  Local $pUIElement
	  $oParent.FindFirst($TreeScope_Descendants, $pCnd, $pUIElement)
	  $oLink = ObjCreateInterface($pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)

	  If Not IsArray($oLink) Then
		 Sleep(30)
		 ExitLoop
	  EndIf

	  WinActivate("Mozilla Firefox")
	  Send("{ENTER}")
	  ExitLoop
   WEnd
EndFunc


Добавлено:
Сообщение автоматически объединено:

inververs, нет, неоткуда ему там взяться, да и на разных сайтах наблюдается. :scratch:
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Код:
If Not IsArray($oLink) Then
         Sleep(30)
         ExitLoop
      EndIf

$oLink - это объект, на массив его проверять не нужно.
И вместо ENTER вы можете выполнить doDefaultAction по кнопке, найти ее можно как потомок этого окна.
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
Сделал вот так:

Код:
#include "UIAutomate.au3"

Func UE() ; Закрываем ошибку "Unexpected Error"
     Opt("WinTitleMatchMode", 2)
   Do
       $oParent = _UIA_GetElementFromHandle(WinActivate("Mozilla Firefox"))
       Sleep(30)
   Until IsObj($oParent)

   While 1
      $pCnd = _UIA_CreatePropertyCondition("Name", "Unexpected Error")
      Local $pUIElement
      $oParent.FindFirst($TreeScope_Descendants, $pCnd, $pUIElement)
      $oLink = ObjCreateInterface($pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)

      If @error Then
         Sleep(30)
         ExitLoop
      EndIf

      WinActivate("Mozilla Firefox")
      Send("{ENTER}")
      ExitLoop
   WEnd
EndFunc

Не работает. Что не так делаю?
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
Что конкретно не работает? Окно не находит? Текст не находит? Enter не нажимает?
Ошибки с префиксом "!> _UIA_" в консоль SciTE выводятся?
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
InnI, не ругайтесь. Это окошко по заказу не выпадает, его еще выловить надо, для этого приходится сидеть у монитора. Я мог бы уже и не париться, так как по совокупности пикселей с заданными цветами отлавливается "на ура", просто хочется решить проблему с помощью Вашей библиотеки. А раз не совсем въезжаю в суть ее работы, то и спрашиваю - в принципе есть в коде ошибки или нет?

Не отыскивается текст, по нему произвожу поиск. Вот что в отладчике:

Код:
_FFLoadWait: ................................................................. loaded in 23073ms
[object HTMLDocument] - {location: {...}, sm2movie: function() {...}, searchform: {...}, tpix_179357: {...}, location: {...}, getElementsByName: function() {...}, getItems: function() {...}, ...}
__FFSend: FFau3.WCD=window.content.top.document;
__FFRecv: [object HTMLDocument] - {location: {...}, sm2movie: function() {...}, searchform: {...}, tpix_179357: {...}, location: {...}, getElementsByName: function() {...}, getItems: function() {...}, ...}
[object HTMLDocument] - {location: {...}, sm2movie: function() {...}, searchform: {...}, tpix_179357: {...}, location: {...}, getElementsByName: function() {...}, getItems: function() {...}, ...}
>Exit code: 0    Time: 110
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
bescom [?]
Это окошко по заказу не выпадает, его еще выловить надо, для этого приходится сидеть у монитора.
ИМХО, можно сделать html-файл с кодом
Код:
<html>
<head>
<title>alert</title>
</head>
<body>
<script type="text/javascript">alert("Unexpected Error");</script>
</body>
</html>
Запускать его через Mozilla Firefox и отлавливать это окно.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
И в каком месте вы ругань увидели? Я просто задал вопросы, без ответов на которые сложно чем-то помочь. Неужели вы не понимаете, что фраза "не работает" не говорит ни о чём? (и это я опять не ругаюсь)

Не отыскивается текст
Хорошо. Давайте по старой схеме - через отладочный скрипт
Код:
#include "UIAutomate.au3"

Opt("WinTitleMatchMode", 2)
Global $pParent, $pCondLink, $pCondValue, $pCondAND, $pCondTrue, $pUIElement, $pUIElementArray, $iElements
LogErr("-----------------------------", 0)

$hWnd = WinActivate("Mozilla Firefox")
If Not $hWnd Then LogErr("Окно Firefox не найдено", 1)

$oUIAutomation = ObjCreateInterface($sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation)
If Not IsObj($oUIAutomation) Then LogErr("Ошибка создания объекта UIAutomation", 1)

$ErrCode = $oUIAutomation.ElementFromHandle($hWnd, $pParent)
LogErr("ElementFromHandle ErrCode " & Hex($ErrCode))
$oParent = ObjCreateInterface($pParent, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
If Not IsObj($oParent) Then LogErr("Ошибка создания объекта по идентификатору окна", 1)

$ErrCode = $oUIAutomation.CreatePropertyCondition($UIA_NamePropertyId, "Unexpected Error", $pCondLink)
LogErr("CreatePropertyCondition (Name) ErrCode " & Hex($ErrCode))
If Not $pCondLink Then LogErr("Ошибка создания условия поиска имени", 1)

$ErrCode = $oParent.FindFirst($TreeScope_Descendants, $pCondLink, $pUIElement)
LogErr("FindFirst (Name) ErrCode " & Hex($ErrCode))
$oUIElement = ObjCreateInterface($pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
If Not IsObj($oUIElement) Then LogErr("Ошибка создания объекта (Name)", 1)
LogErr("Объект с именем 'Unexpected Error' найден : " & _UIA_ElementGetPropertyValue($oUIElement, "ControlType"))

ShellExecute("LogErr.txt")

; --------------------------

Func LogErr($str, $exit = 0)
  FileWriteLine("LogErr.txt", $str)
  If $exit Then
    ShellExecute("LogErr.txt")
    Exit
  EndIf
EndFunc
С файлом, который предложил madmasles, у меня работает и ваша функция UE() и мой отладочный скрипт.
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
InnI [?]
И в каком месте вы ругань увидели?
Я же пошутил... ;)

С файлом, который предложил madmasles, у меня работает и ваша функция UE() и мой отладочный скрипт.
С этим файлом и у меня все работает отлично. А на реальной странице - нет, не отлавливается. Вот отчет с файла:

Код:
ElementFromHandle ErrCode 00000000
CreatePropertyCondition (Name) ErrCode 00000000
FindFirst (Name) ErrCode 00000000
Объект с именем 'Unexpected Error' найден : 50004

А вот отчет со страницы:

Код:
ElementFromHandle ErrCode 00000000
CreatePropertyCondition (Name) ErrCode 00000000
FindFirst (Name) ErrCode 80004005
Ошибка создания объекта (Name)

Я уже подумываю, не уконтропупить ли насовсем JS в браузере...
К слову сказать, мой способ отлавливания по цветам по более трезвым рассуждениям - бред, потому как стоит измениться теме оформления Win, и вся его работа свалится.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
отчет со страницы
Тот же код ошибки, что и у FindAll: 0x80004005. Я не знаю, что означает эта ошибка и не понимаю, как Inspect этот объект находит. Чтобы понять, мне нужно "ковырять" это всё самостоятельно, но я не могу данную ситуацию повторить.
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
InnI [?]
Чтобы понять, мне нужно "ковырять" это всё самостоятельно, но я не могу данную ситуацию повторить
Могу сделать копию виртуальной машины и закинуть на облако.
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
Завтра будет. Сегодня уже не успею, у нас уже скоро ночь. Или приготовлю сегодня, а завтра пришлю.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
Значит так. Успех поиска зависит от общего количества элементов, среди которых происходит поиск, и это количество ограничено. Для FireFox примерно 9000 на WinXP и около 18500 на Win7 (обе системы x86). При загруженной странице http://bescomblog.com/?page_id=4089 (далее просто страница) для FireFox обнаруживается примерно 4550 элементов (всего, вместе с меню, панелями и др.). Поэтому при одной вкладке работает и поиск ссылок и закрытие окна. При двух вкладках этой страницы не работает ничего, т.к. общее количество элементов превышает порог (FireFox, в отличие от других браузеров, не удаляет объекты неактивных страниц и с каждой страницей их становится больше. На Win7 можно открыть 5 страниц и поиск тоже выдаст ошибку). Но, нашёл старую машину с реальной WinXP, на которой поиск не работает даже с одной страницей, т.е. на этой машине граница в районе 4000 элементов. И ещё. На вашей виртуальной машине порог в районе 8200 элементов, а на моей (тоже WinXP) - около 9200. Подозреваю, что зависит ещё и от машины, на которой установлена виртуалка. Так что проблема понятна - это предел количества элементов для конкретной конфигурации.

Что могу предложить для решения проблемы с окном ошибки? Вариант такой: находить элемент в фокусе (кнопку) и от него искать текст. Если скрипту не мешать, то работает нормально. Но если фокус собьётся, то кнопка нажата не будет
Код:
#include "UIAutomate.au3"

UE()

Func UE()
  Opt("WinTitleMatchMode", 2)
  $oParent = _UIA_GetElementFromHandle(WinActivate("Mozilla Firefox"))
  If @error Then Return
  $oElement = _UIA_GetFocusedElement()
  If @error Then Return
  If _UIA_ElementGetPropertyValue($oElement, "ControlType") = $UIA_ButtonControlTypeId Then
    $oPrev = _UIA_ElementGetPreviousNext($oElement)[0]
	If @error Then Return
    If _UIA_ElementGetPropertyValue($oPrev, "ControlType") = $UIA_TextControlTypeId Then
	  $oChild = _UIA_ElementGetFirstLastChild($oPrev)[0]
	  If @error Then Return
	  If _UIA_ElementGetPropertyValue($oChild, "Name") = "Unexpected Error" Then _UIA_ElementDoDefaulAction($oElement)
    EndIf
  EndIf
EndFunc
Это скрипт для версии UDF 1.2. В последней 1.3 функция _UIA_ElementDoDefaulAction переименована в _UIA_ElementDoDefaultAction. Будьте внимательны при обновлении UDF.
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
InnI, а может, допустимое количество элементов зависит от размера оперативы? Как-то вот это мне представляется более реальным, чем просто где-то выставленное ограничение...

InnI [?]
нашёл старую машину с реальной WinXP, на которой поиск не работает даже с одной страницей
У меня скрипт работает именно с одной открытой вкладкой FF, принудительно в about:config настроено так, чтобы по клику страница открывалась в той же вкладке, несмотря даже на атрибут _blank. Это я к тому, что в моем случае открытие двух и более вкладок исключено.

Пойду пробовать новый вариант закрытия окошка с ошибкой, по результатам отпишусь.
К слову: Вы оценили мою врожденную способность сразу же врюхиваться в ситуацию, которая даже для Вас, автора библиотеки, оказывается в новинку? ;) Могу тестировщиком работать...

32593-dont--t.jpg
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
bescom
может, допустимое количество элементов зависит от размера оперативы
Может быть. Не знаю. Но точно знаю, что зависит от приложения и от типа элементов. И ещё знаю, что цифра эта плавающая - при одном запуске может найти, при следующем - нет. Причём при таком поиске - "на границе" - может находить разное количество элементов.

открытие двух и более вкладок исключено
Я предупредил. Решать вам.

оказывается в новинку
Не совсем. Про ограничение количества я знал. Просто не ожидал такой большой разницы между WinXP и Win7. А тут ещё и виртуалки свои коррективы вносят.
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
InnI, сейчас тестирую на двух машинах, как раз самых проблемных. Пока работает, как часики. Буду держать в курсе и периодически сообщать, как идет тестирование, если не накажут за поднятие темы, например. :-[
 
Автор
bescom

bescom

Новичок
Сообщения
61
Репутация
0
InnI, работает великолепно, без единого сбоя. Огромное спасибо! :beer:
 
Верх