Страницы: 1
RSS
Ошибка 800c0008 при работе с XMLHTTP
 
Доброй ночи.
Исходные:
Использую VBA макросы (самописные) для управления магазина на платформе Insales. У них прекрасное API и необходимая документация.
Система Win 7 (64), Excel 2010 (64). Использую библиотеку Microsoft xml, v6.0
Суть проблемы:
Код передает запросы на сайт, и если запросов не много, не более 1000 - все нормально.
Часть кода:
Скрытый текст
Функция которая передает код:
Скрытый текст
Но необходимо передавать по 20-100 тысяч запросов. И тут рандомно с частотой 1000-2500 запросов выскакивает ошибка 800c0008 (см. скриншот)

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

PS. В коде присутствуют временные задержки - тех. часть (не более 500 запросов в 5 мин) и еще по секунде поставил после каждого запроса - не помогло.
Пробовал и по wifi к интернету подключаться и по кабелю - выскакивает ошибка.
 
Вероятных причины две:

1) вы некорректно формируете передаваемый XML
Код
 'создание тела запроса
        myxml = "<?xml version=""1.0"" encoding=""UTF-8""?><filter>"
...
... ' неизвестно что тут за код - может в нем что не так
Цитата
Использую библиотеку Microsoft xml, v6.0
Судя по вашему коду, - вы НЕ используете эту библиотеку (по крайней мере, для формирования корректного XML),
а формируете XML путем сцепления кусков текста. Что не есть хорошо (мало ли там какой недопустимый символ, - и XML невалидным будет)

2) сервер из-за перегруженности некорректно отвечает на ваш запрос

Что тут сделал бы я:
- в функцию Function SendPostXML первой строкой добавляем On Error Resume Next: err.clear
(чтобы она по ошибке не вылетала)
- последней строкой в функции пишем: if err<>0 then ... ' тут вы анализируете ответ сервера, заголовки ответа сервера
Это надо, чтобы понять причину ошибки.
Если с причиной разбираться лень, - можно в случае ошибки просто повторно вызвать эту же функцию с теми же параметрами:
Код
if err then SendPostXML=SendPostXML(str, myxml, Status, statusText, responseText) ' в надежде, что не зациклится
Наиболее вероятна причина номер 2 (поскольку ошибка появляется случайным образом)
Изменено: Игорь - 27.10.2016 01:15:17
 
Спасибо что откликнулись.
1. Я использую библиотеку только для отправки. Формирую сам. Формирую правильно. Если все таки выскакивает недопустимый символ - это совершенно другая ошибка. Выскакивало - знаю.
2. Попробую

А у вас была такая ошибка или вы логически вычислили?
 
Конкретно такой ошибки не было
Просто есть опыт подобных запросов из VBA к разным сайтам, - отсюда делаю выводы

Код, конечно, не идеален, - но, полагаю, проблема всё же в сайте
Такие ошибки, обычно, возникают по причине сервера, или канала связи с ним
 
Такая ошибка обычно означает, что запрашиваемый файл недоступен по каким-либо причинам.
Игорь не одну собаку съел на таких делах :) к его п.2 можно лишь добавить очевидное - покрутиться немного (несколько секунд) в цикле ожидания с DoEvents, и если ошибка не устранилась за время цикла, то вывести сообщение и завершить код.
Еще при множественных запросах подряд в цикле уборщик мусора (очистка не освобожденной памяти объектных переменных) может не успевать очищать память. Чтобы предупредить такое дело и для ускорения работы можно немного изменить начало кода функции:
Код
Private Function SendPostXML(str, myxml, Status, statusText, responseText)
  Static myHTTP As MSXML2.XMLHTTP       'HTTP variable
  Static myDom As MSXML2.DOMDocument    'DOMDocument variable
  If myHTTP Is Nothing Then
    Set myHTTP = New MSXML2.XMLHTTP     'Create HTTP object
    Set myDom = New MSXML2.DOMDocument  'Create DOMDocument Object
    myDom.async = False                 'Disable Async mode
  End If
  myDom.LoadXML myxml
  ' ... и т.д. ...
End Function

Объекты при этом будут создаваться один раз и очищаться при выходе из Excel или при VBE-Run-Reset, а не тысячи раз создаваться-уничтожаться при каждом запросе.
Изменено: ZVI - 27.10.2016 05:38:59
 
ZVI,Спасибо!
Много новой информации для меня.
Внедрю цикл при ошибках Игоря и ваш кусочек кода.

О результатах отпишусь, после тестирования на большие объемы

PS Конкретно в этом коде скорость значение не имеет, тк есть ограничение со стороны принимающей стороны 500 запросов в 5 мин. Я думаю вообще оставить только задержку 1 сек после каждого запроса, получится минимум 500 сек, а это с запасом больше чем 300 сек (5 мин). Так что чистку памяти можно исключить (но код вставлю - он грамотней).
Я больше склоняюсь к ошибкам на сервере. Но буду тестировать и подключение кабелем, что бы исключить ошибки wi-fi.
Изменено: peter200 - 27.10.2016 11:10:58
 
ZVI, Игорь, большое вам спасибо за помощь.
В итоге проблему заборол. 15000 запросов зашло со скрипом, но зашло. Мне кажется все таки сервер скрипит, не хочет он столько обрабатывать))
Итоговый код:
Код
'POST
Private Function SendPostXML(str, myxml, Status, statusText, responseText, errflag)
    On Error Resume Next 'отключаем выскакивание окошка об ошибке и переходим к следующему оператору после ошибки
    Err.Clear 'стираем ошибки в массиве ошибок
    Dim i 'счетчик
    errflag = 0
    Static myHTTP As MSXML2.XMLHTTP 'HTTP variable
    Static myDom As MSXML2.DOMDocument 'create dom document variable 'stores the xml to send
    If myHTTP Is Nothing Then 'создаем объекты если еще не были созданы на пердыдущей итерации
        Set myHTTP = New MSXML2.XMLHTTP 'HTTP object
        Set myDom = New MSXML2.DOMDocument 'Create the DomDocument Object
        myDom.async = False 'Load entire Document before moving on
    End If
    myDom.LoadXML myxml
    myHTTP.Open "POST", str, False 'open the connection
    myHTTP.setRequestHeader "Content-Type", "application/xml"
    myHTTP.Send myDom.XML 'send the XML - !!!именно здесь вываливается ошибка!!!
    i = 1
    Do While Err 'цикл по ошибке
        Err.Clear
        Application.Wait Now + TimeSerial(0, 0, 10) 'пауза
        myHTTP.Send myDom.XML 'send the XML, снова пытаемся отправить запрос
        i = i + 1
        If i = 10 Then 'через 10 безуспешных попыток уходим
            errflag = 1
            Exit Function 'выход из программы, если 10 ошибок подряд
        End If
    Loop
    Status = myHTTP.Status '201
    statusText = myHTTP.statusText 'Created
    responseText = myHTTP.responseText 'Вся простыня ответа сервера
End Function

Попинайте, если есть косяки)
 
ну вот, теперь с кодом всё ок, - даже докопаться не до чего)
а главное - работает
 
Да - работает, это главное.
Всем спасибо, кто откликнулся и потратил свое время на помощь.

Код признали неплохим, надеюсь еще кому-нибудь пригодится.
Напомню: код для отправки запросов на сервер (API Insales), сервер периодически выдавал ошибку и код останавливался.
Был сделан небольшой обработчик ошибки (просто пауза), счетчик ошибок (что бы код не зациклился) и выход из функции при достижении 10 ошибок подряд.
Код выше.
Страницы: 1
Читают тему
Наверх