- @Helgef: I'm not sure what you wish to mean by splicing those two quotes together. As an example, I don't use 'local', but other people asked me to support it in my functions. Error handling could result in something similar.
- I had a plan that if I had an old script that I'd converted to AHK v2, and there was a new kind of error, e.g. a maths error, I would use hotkeys to block keyboard/mouse input to the error MsgBox, so as to not accidentally click Yes or No, and then invoke a click on Yes to 'Continue running the script?'.
- That way I could learn about the new errors and update my scripts, but not have my scripts crash unexpectedly, due to new error criteria, and so avoid losing data.
- CRUCIALLY it seems that AHK errors are generally/always of the 'The current thread will exit.' kind and not of the 'Continue running the script?' kind, scuppering these ideas.
- I think it's worth mentioning all of the issues relating to errors:
- 'The current thread will exit.' v. 'Continue running the script?'
- AHK v2 has stricter error handling.
- Not clicking Yes or No accidentally on a MsgBox. (And/or error messages with a SoundBeep and/or time delay so that you can't press the buttons immediately.)
- MsgBoxes getting hidden under other windows.
- Allowing calculations to return a blank string and silently fail versus crash the script.
- Allowing all errors to silently fail. An on/off mode. (Similar functionality to AHK v1.)
- Using 'if ErrorLevel'.
- OnError.
- try/catch/finally, throw, Exception.
- [EDIT:] ErrorLevel is currently used for situations that aren't strictly errors: e.g. InputBox and Sort (remove duplicates).
- Anything else?
- When exactly do you get the 'Continue running the script?' Yes/No options? Does OnError allow this?
- Here is an AHK v1 example, to display some nice 'if ErrorLevel' handling. It keeps the code clear and short.
- There's also a try/catch example, however it gets ugly quickly. The readability declines rapidly, especially when you add in multiple error handling code blocks in otherwise short functions. Can the try/catch example be simplified e.g. the vError variable eliminated?
- My suspicion is that I'll need to remove every instance of ErrorLevel in future, and move to try/catch, but I'm not sure whether try/catch blocks can be made sufficiently succinct.
- Otherwise, if available, a one-liner to suppress error messages within the scope of a function, and using ErrorLevel might be the best option. [EDIT: On/off within a *function*, versus on/off within a *thread*, because otherwise you need to add curly braces to turn the mode on/off before the function ends (before any return line), which clutters the function.]
Code: Select all
;q::
vPath1 := A_Desktop "\blank.txt" ;a file that already exists
vPath2 := A_Desktop "\blank?.txt" ;an invalid path
if !FileExist(vPath1)
FileAppend,, % vPath1
;ErrorLevel
Loop, 2
{
FileMove, % vPath1, % vPath%A_Index%
if ErrorLevel
MsgBox, % "FileMove error"
else
MsgBox, % "FileMove success"
}
;try/catch
Loop, 2
{
vError := 0
try FileMove, % vPath1, % vPath%A_Index%
catch
{
vError := 1
MsgBox, % "FileMove error"
}
if !vError
MsgBox, % "FileMove success"
}
return
- Here are some AHK v2 tests:
Code: Select all
MsgBox("hello")
;ACC
;I couldn't think of any internal-to-AHK examples that give the 'Continue running the script?' prompt (instead of the 'The current thread will exit.' prompt)
;this error gives you the option of whether to terminate the script or not
;Error: 0x80070057 - The parameter is incorrect.
;Continue running the script?
oGui := GuiCreate(, "MyWinTitle")
oLV := oGui.Add("ListView", "r3", "LVH 1")
Loop 3
oLV.Add("Select", A_Index)
oAcc := Acc_ObjectFromWindow(oLV.hWnd)
Loop oAcc.accChildCount
vOutput .= oAcc.accName(A_Index) "`r`n"
MsgBox(vOutput)
;OBJECTS
;this error terminates the script, with no option to continue
;Error: No object to invoke.
;The current thread will exit.
oArray := {}
;MsgBox(oArray.a.b)
;THROW
;this error terminates the script, with no option to continue
;Error: Unhandled exception.
;throw 3
;%CAUSE% := ERROR [based on an example in the documentation for OnError]
;this error terminates the script, with no option to continue
;%cause% := error
;Error: This dynamic variable is blank. If this variable was not intended to be dynamic, remove the % symbols from it.
;The current thread will exit.
;FILEMOVE
;FileMove was allowed to fail silently in AHK v2 which surprised me,
;everything else I'd tested seemed to be regarded as a fatal error,
;but I would prefer an option to suppress error messages,
;and use ErrorLevel checks to ensure that scripts would run correctly
vPath1 := A_Desktop "\blank.txt"
vPath2 := A_Desktop "\blank?.txt" ;invalid path
Loop 2
{
FileMove(vPath1, vPath%A_Index%)
if ErrorLevel
MsgBox("FileMove error")
else
MsgBox("FileMove success")
}
;MATHS
;this works:
vError := 0
vNum := "abc"
try (vNum + 0 = "")
catch
MsgBox("not num"), vError := 1
;how can I know if I there was an error?
;do I need to add the vError variable?
;is there not: try, catch (to handle error), else (if no error)
;MATHS
;this error terminates the script, with no option to continue
;Error: Type mismatch.
;The current thread will exit.
vNum := "abc"
if (vNum + 0 = "")
MsgBox("not num")
Acc_Init()
{
Static h
If Not h
h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromWindow(hWnd, idObject := -4)
{
Acc_Init()
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
Return ComObject(9,pacc,1)
}