Error handling

List of all errors

abort

System command: type \ at the debugger prompt q)) prompt to return to the interactive session.

q)f:{g[]}
q)g:{'`xyz}
q)f[]
{g[]}
'xyz
@
{'`xyz}
::
q))\
q)

exit

Syntax: exit x

where x is a positive integer, exit terminates the q process with x as the exit code.

q)exit 0        / typical successful exit status
..

q)exit 42
guest@localhost:~$ echo $?
42

.z.exit (action on exit)

' (signal)

Syntax: 'emsg

where emsg is a symbol or char list, signal aborts evaluation and passes msg to the interpreter as a string.

q)0N!0;'`err;0N!1
0
'err

The only way to detect a signal is to use trap.

q)f:{@[{'x};x;{"trap:",x}]}
q)f`err
"trap:err"

Trap always receives a string regardless of the type of x.

Signal has some restrictions


q)f 1         / signals a type error indicating ' will not signal a number
"trap:stype"
q)f"a"        /q will not signal a char
"trap:stype"
Using an undefined word signals the word as an error

q)'word
'word
which is indistinguishable from

q)word
'word

. @ (trap)

Syntax: @[f;fx;e]
Syntax: .[g;gg;e]

Where

  • f is a unary function and fx is its argument
  • g is a multi-argument function and gg is a list of its arguments
  • e is an expression, typically a function

Trap will evaluate function e if evaluation of f or g fails. It is similar to try/catch in other languages.

When there is no signal, @ behaves like binary @.

q)@[string;42;`err]
"42"

When there is a signal the result of the trap is e.

q)@[{'x};"signal this";`err]
`err

If e is a function, it is called with the signal as argument.

q)@[2+;"42";{"Caught: ",x}]
"Caught: type"

This can be used to return a result unambiguously indicating whether the function succeeded. Here, the first item of the pair indicates success or failure, while the second item is either the result or the error. This is useful when 0 or () might be valid results.

q)@[(1b;){1+x}@;0;(0b;)]
1b
1
q)@[(1b;){1+x}@;`a;(0b;)]
0b
"type"
q)

Limit of the trap

Trap catches only errors signalled in the applications of f or g. Errors in the evaluation of fx or gg themselves are not caught.


q)@[2+;"42";err]err
q)@[2+;"42"+3;err]
'type
  [0]  @[2+;"42"+3;err]
                ^

@[f;fx;e] is equivalent to .[f;enlist fx;e]. "dot" trap is used for multi-argument f.

q).[*;(42;42);`err]
1764

Examples:

q)@[parse;"1b1";`err]
`err
q)@[parse;"22 1b1 44";::]
"1b1"

When e is not a function

If e is a function it will be evaluated only if f or g fails. It will however be parsed before any of the other expressions are evaluated.


q)@[2+;"42";{)}]
')
  [0]  @[2+;"42";{)}]
                  ^
If e is any other kind of expression it will always be evaluated – and first, in the usual right-to-left sequence. In this respect trap is unlike try/catch in other languages.

q)@[string;42;a:100] / expression not a function
"42"
q)a // but a was assigned anyway
100
q)@[string;42;{b::99}] / expression is a function
"42"
q)b // not evaluated
'b
  [0]  b
       ^
For most purposes, you will want e to be a function.