Skip to content

Instantly share code, notes, and snippets.

@zero-plusplus
Last active November 25, 2023 14:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zero-plusplus/107d88903f8cb869d3a1600db51b7b0a to your computer and use it in GitHub Desktop.
Save zero-plusplus/107d88903f8cb869d3a1600db51b7b0a to your computer and use it in GitHub Desktop.
Suppresses run-time error dialogs and outputs more detailed information to standard output.
/**
* @licence MIT <http://opensource.org/licenses/mit-license.php>
* @auther zero-plusplus
* @link https://gist.github.com/zero-plusplus/107d88903f8cb869d3a1600db51b7b0a
*/
#ErrorStdOut, UTF-8
/**
* Suppresses run-time error dialogs and instead outputs their contents to standard output.
*
* @param {boolean} [enable := true]
* @example
* #Include <SuppressErrorDialog>
*
* ; Just include it and it will work
* throw Exception("Some error") ; Output to standard output instead message box
*
* SuppressErrorDialog(false)
* throw Exception("Some error") ; The error is displayed in the message box as usual
*/
SuppressErrorDialog(enable := true) {
static _init_ := SuppressErrorDialog()
OnError("SuppressErrorDialog_OnError", enable)
}
SuppressErrorDialog_OnError(exception) {
static ERROR_CODE := 2
if (!IsObject(exception)) {
exception := Exception(exception, -1)
}
message := Format("{} ({}) : ==> {}", exception.file, exception.line, exception.message)
if (exception.extra) {
message .= "`n Specifically: " . exception.extra
}
stacks := SuppressErrorDialog_CallStack()
if (0 < stacks.length()) {
message .= "`n`n[Call Stack]"
for i, stack in stacks {
message .= Format("`n> {}:{} : [{}]", stack.file, stack.line, stack.what)
}
}
OutputDebug, %message%`n
ExitApp, %ERROR_CODE%
}
SuppressErrorDialog_CallStack()
{
stacks := []
startFrame := 2
while (true) {
e := Exception("", -(startFrame + (A_Index - 1)))
if ((e.what + 0) != "") {
break
}
stacks.push(e)
}
; The what properties are off by one, unlike the actual stack properties (v2 only properties), so fix them here
if (0 < stacks.length()) {
for i, stack in stacks {
if (i + 1 <= stacks.length()) {
nextStack := stacks[i + 1]
stack.what := nextStack.what
}
}
stacks[stacks.length()].what := "Auto-execute"
}
return stacks
}
/**
* @licence MIT <http://opensource.org/licenses/mit-license.php>
* @auther zero-plusplus
* @link https://gist.github.com/zero-plusplus/107d88903f8cb869d3a1600db51b7b0a
*/
#ErrorStdOut "UTF-8"
/**
* Confirmed in v2.0-beta.1
* Suppresses run-time error dialogs and instead outputs their contents to standard output.
*
* @param {boolean} [enable := true]
* @example
* #Include <SuppressErrorDialog> ; Note: Please rename the extension from `ahk2` to `ahk`.
*
* ; Just include it and it will work
* throw Error("Some error") ; Output to standard output instead message box
*
* SuppressErrorDialog(false)
* throw Error("Some error") ; The error is displayed in the message box as usual
*/
SuppressErrorDialog()
SuppressErrorDialog(enable := true) {
OnError(ErrorHandler, enable)
return
GetCallStack() {
stacks := []
startFrame := 2
while (true) {
e := Error("", -(startFrame + (A_Index - 1)))
if (e.what == "" || IsNumber(e.what)) {
break
}
stacks.push(e)
}
; The what properties are off by one, unlike the actual stack properties, so fix them here
if (0 < stacks.length) {
for i, stack in stacks {
if (i + 1 <= stacks.length) {
nextStack := stacks[i + 1]
stack.what := nextStack.what
}
}
stacks.pop() ; The last stack should be removed because it is covered with information
}
return stacks
}
ErrorHandler(err, mode) {
static ERROR_CODE := 2
mostRecentStack := Error(err, -1)
if (!IsObject(err)) {
err := mostRecentStack
}
; The file and line numbers in the error we received are somehow off by one stack and need to be fixed
err.file := mostRecentStack.file
err.line := mostRecentStack.line
message := Format("{} ({}) : ==> {}", err.file, err.line, err.message)
if (err.hasOwnProp("extra") && err.extra !== "") {
message .= "`n Specifically: " . err.extra
}
stacks := GetCallStack()
if (0 < stacks.length) {
message .= "`n`n[Call Stack]"
for i, stack in stacks {
message .= Format("`n> {}:{} : [{}]", stack.file, stack.line, stack.what)
}
}
OutputDebug(message "`n")
ExitApp(ERROR_CODE)
}
}
@zero-plusplus
Copy link
Author

zero-plusplus commented Sep 16, 2020

Please report any bugs here.

@SAbboushi
Copy link

Thanks for this

@zero-plusplus
Copy link
Author

The following changes have been made.

  • The files have been split for each version of AutoHotkey. This makes the source code more readable
  • The source code for v2 is now compatible with a138. Note that it is not guaranteed to work with earlier versions.
  • Changed the function names to clearly express the behavior
  • Changed to display the call stack

@zero-plusplus
Copy link
Author

The following changes have been made.

  • Changed to output error information and stack information more accurately
  • Fixed differences in output between different versions

@zero-plusplus
Copy link
Author

zero-plusplus commented Aug 24, 2021

The following changes have been made.

  • The error output has been changed from FileAppend to OutputDebug to support the next version of vscode-autohotkey-debug (1.8.0)
  • Made it so that just reading the file will have an effect. Previously, it was necessary to call a function

@zero-plusplus
Copy link
Author

The following changes have been made.

  • Fixed a issue where the /ErrorStdOut setting was not working when this script was loaded using the /include argument in the AutoHotkey runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment