Handle run-time errors

Syntax1 - on error, continue

err[+|-]

 

Syntax2 - on error, execute code and continue

err[+|-]
(tab)	statement
(tab)	...
...

 

Can be in single line:

err[+|-] statements

 

Parts

statements - any statements that are executed only on error.

Options:

+ handle errors from all preceding statements (or from all preceding statements that follow err-).

- marks the beginning of the block of statements guarded by err+.

Default: handle errors only from the preceding statement.

 

Remarks

By default, when an error occurs in a macro, the macro ends. To continue the macro, you can use err. When an error occurs, QM looks for err in the next statement, or err+ in some statement forward. If finds, execution continues after that err or err+. If not, macro ends.

 

err handles QM-generated errors ("Window not found", "Cannot copy file", etc), user-generated errors (end), and exceptions (errors generated by the operating system). It does not handle some fatal errors such as "noncompiled function". It does not handle compile-time errors.

 

When an error occurs, special variable _error is filled with information about the error. Type is QMERROR:

 

type QMERROR ~description code iid source place ~line

 

description - string that you can see in QM output when error is generated.

code - associated numeric value.

iid - id of QM item where the error is generated. Use str.getmacro to get item name. Use getopt to get macro entry.

source - one of the following values: 0 - no error, 1 - compile-time error, 2 - run-time error generated by QM, 3 - run-time error generated by end, 4 - exception (run-time error generated by the operating system).

place - offset of the statement in macro text.

line - the statement.

 

_error has thread scope, that is, is accessible in all functions of that thread, including functions registered to run when thread ends (atend). In function registered by atend, _error is empty if the thread ended normally, or is populated with the error info if the thread ended due to an error.

 

err handles errors generated in current function only. It does not handle errors generated in user-defined functions that are called from current function. However, called functions can pass their errors to the caller. If you want that errors generated in current function would be passed to the caller function, handle them with err+ at the end, and use end _error in the error handler code. It is like catch(...){throw;} in C++. See the example.

 

Tips

Run-time errors are not generated if run-time option opt err 1 is set.

 

See also: Common errors

 

Examples

 Close "Notepad" window if it exists, and don't generate error if it does not exist:
clo "Notepad"; err

 Close all "Notepad" windows:
rep
	clo "Notepad"
	err break

 On error, display error description:
...
err
	mes _error.description

 Always free allocated memory:
int* p=calloc(10 4)
...
err+
free p

 Handle errors from all preceding statements and generate them in caller:
...
err+ end _error

__________________________________

 If macro ends due to an error, log the error to file 'My Documents\My QM\qm log.txt':

 Insert this at the beginning of each macro that needs error logging:
atend LogErrors

 And create function LogErrors:
if(_error.source) ;;macro ended due to an error
	str macroname.getmacro(getopt(itemid 3) 1)
	str functionname.getmacro(_error.iid 1)
	str s.format("Macro %s ended due to an error in %s.[]Error description: %s[]Error line: %s[]" macroname functionname _error.description _error.line)
	LogFile s 1