1

Тема: AHK: Принцип работы try/catch

Здравствуйте, товарищи. В своем скрипте я использую HTTP запросы и периодически (как я понял причиной является лаги компьютера или сервера к которому обращаюсь, в общем независящие от скриптера) метод Waitforresponse объекта WinHPPTRequest 5.1 выдает ошибку. Этот скриншот лишь демонстрирует одну из них. Я не смог выявить закономерности появления ошибки потому мне трудно установить причину, однако мне крайне необходимо перехватить это событие, чтобы не выводить диалоговое окно об ошибке. В справке я наткнулся на команды try/catch, которые вроде бы могут мне помочь с этим, однако, мне ничерта не понятно ни с описания той команды, ни с примеров, приведенных в статье, из которых я увидел лишь демонстрацию вложенности этих операторов. Потому я прошу мне объяснить суть работы этих операторов, чтобы я смог их применить для перехвата ошибок в будущем.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

2 (изменено: serzh82saratov, 2019-04-10 00:42:59)

Re: AHK: Принцип работы try/catch

Try Gui, Show, wXXXX
Catch
	MsgBox Не правильно задан параметр

Просто прописать "Try" перед строкой с возможной ошибкой.
Но в случае с ComObj лучше применить в начале скрипта ComObjError(false). Ошибки проверять по результатам функций. Будет непонятно где ошибка, проще закоментировать одну строку, чем удалять Try которые без Catch.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

3 (изменено: svoboden, 2019-04-11 04:18:50)

Re: AHK: Принцип работы try/catch

Может, OnError() проще будет.

4

Re: AHK: Принцип работы try/catch

Согласен, удобная штука, никогда не использовал.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

5

Re: AHK: Принцип работы try/catch

Но только он завершает поток, что в большинстве случаев не подходит. То есть это удобная замена для "Throw", а не для "Try".

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

6

Re: AHK: Принцип работы try/catch

Думаю, стоит подробней пояснить.
Try -> Catch — предназначен для организации логики при возникновении ошибок, несовместимых с выполнением программы. Семантически, в блок "Try {}" помещается участок кода, который подозревается в генерации таких событий, а содержимое "Catch {}", выполняет его перехват и обработку, если необходимо, для чего имеет связанную переменную, получающую "состояние" исключения, если оно документировано и может выполнить альтернативный алгоритм, чтобы попытаться осуществить предыдущую задачу похожим способом. "Exception" на Вашем скрине, сообщает, что "Время ожидания операции истекло". Если Вы его перехватите в "Catch e {}", "e.Message" будет содержать об этом пояснение.

В примере из справки показано, как по соглашению документированы исключения, чтобы их можно было не просто избегать, но так же строить логику с их участием. Exception() предоставляет для этого нативную возможность построения такого "документирующего" объекта, передаваемого в Throw. Так же их можно генерировать и "документировать" самому, не забыв при том, опубликовать их список и структуру, если собираетесь сделать фреймворк для пользования другими.


try 
    SomeFunction()
catch e {
    MsgBox % "Error in " e.What ", which was called at line " e.Line "`n" e.Message
	Try {
		AnotherFunction()
		; Код, который не сможет быть выполнен
	} Catch e {
		MsgBox % Format("Перехвачено исключение типа '{}', с результатом выполнения '{}', сообщающее следующее:`n$$$ '{}' $$$", e.type, e.code, e.msg)
		; Остальная часть этого блока будет выполнена, если не сгенерирует новое исключение
	}
}

ExitApp

SomeFunction() {
    throw Exception("Fail", -1)
}
AnotherFunction() {
	throw {"type": "ФАТАЛ ЭРРОР!!!", "code": 101, "msg": "Сушите вёсла, приехали!"}
}

7 (изменено: wladkokopops, 2019-04-10 08:42:11)

Re: AHK: Принцип работы try/catch

ComObjError(false) ;Вот эту строчку используй TRUE даст все вышедшие ошибки при подключению, false будет игнорировать
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
whr.Open("POST", "URL", true) 
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36") 
whr.SetRequestHeader("Content-Type","application/x-www-form-urlencoded") 
whr.Send() 
whr.WaitForResponse() 
jsontext := % whr.ResponseText

8

Re: AHK: Принцип работы try/catch

Спасибо за ответы. Значит с этой конкретной проблемой лучше воспользоваться будет ComObjError.

KusochekDobra, как я понял, мы помещает в try тот код, который может вызвать ошибку времени выполнения и если таковая случается, выполняется код в блоке catch, верно? Что в Вашем примере, что в справке, показаны команды Throw - она, скажем так, принудительно генерирует сообщение об ошибке? Ну например в том же HTTP запросе, если по завершению сценария в ResponseText ничего нет то это явно ошибка и в таком случае, чтобы вызвать блок catch я прописываю Throw в условии верно?

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

9

Re: AHK: Принцип работы try/catch

Генерация исключения(Throw) — полезна, если Вы не знаете, в каком логическом окружении будет работать текущий участок кода, но Вы определённо знаете, что именно этот участок, требует определённого поведения для корректной работы. Как раз это и описано в реализации WinHttpRequest. В какой-то части кода предусмотрено получение ответа от сервера. Ответ не может быть ожидаем бесконечно, поэтому ожидается его получение согласно настройкам таймаутов и если в течение этого времени ответ не приходит, вызванный метод не может вернуть ожидаемый результат, в следствии чего, его код генерирует такое исключение, описывая само событие чтобы разработчик, использующий этот сторонний код, мог адекватно реагировать на ситуацию.

Сам метод вызываете Вы, из своего кода, значит вместо возвращаемого результата код получает сгенерированное вызванным методом исключение. Помимо этой ошибки, есть и другие. Например, когда соединение было внезапно потеряно, или возвращённый от сервера результат оказался нераспознанным. В каждом таком случае можно совершить ряд действий для продолжения работы программы перехватив исключение и получив информацию о том, что же его вызвало. Например, попытаться вновь совершить запрос, или обратиться к другому, запасному серверу за подобной информацией...

В Вашем случае, чтобы бесконечно ломиться на сервер в ожидании ответа, должно быть как-то так:


if (!(result := Get("http://forum.script-coding.com").error)
	MsgBox % result
else
	MsgBox % "Статус запроса = " result.error "`n" result.req

Get(url) {
	oHTTP := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	Try {
		oHTTP.Open("GET", url, false)
		oHTTP.Send()
		oHTTP.WaitForResponse()
	} Catch e {
		; 0x80072F78	Сервер вернул недопустимый или нераспознанный ответ
		; 0x80072EE2	Время ожидания операции истекло
		; 0x80072EFE	Соединение с сервером было неожиданно прервано
		OutputDebug % e.Message
		Return Get(url)
	} Return oHTTP.Status == 200 ? oHTTP.ResponseText : {"error": oHTTP.Status, "req": oHTTP.ResponseText}
}

И для отладки не особенно-сложных сценариев, используйте OutputDebug совместно с DebugVew. Это существенно упростит логгирование процесса без необходимости создания файла.

10

Re: AHK: Принцип работы try/catch

KusochekDobra, теперь я понял логику работы этих команд, спасибо.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

11 (изменено: stealzy, 2019-04-10 19:33:53)

Re: AHK: Принцип работы try/catch

UrlDownloadToVar - используется try/catch, если вашу ошибку не будет ловить, пишите в тему, улучшим функцию вместе.