Software Development

kdb+/q – Try Catch

Programming languages typically have a try-catch mechanism for dealing with exceptions. The try block contains the code you want to execute and the catch block contains the code that will be executed if an error occurs in the try block.

Here is an example of a simple try-catch block in Java, which attempts to parse a string into an int and returns -1 if there is an error.

1
2
3
4
5
6
try {
    return Integer.parseInt(x);
} catch (NumberFormatException e) {
    e.printStackTrace();
    return -1;
}

In this post, I will describe the try-catch equivalent for exception handling in the q programming language.

.Q.trp[f;x;g] – for unary functions

For unary functions, you can use .Q.trp (Extend Trap), which takes three arguments:

  1. f – a unary function to execute
  2. x – the argument of f
  3. g – a function to execute if f fails. This function is called with two arguments, the error string x and the backtrace object y

For example:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Define a function which casts a string to int
parseInt:{[x] "I"$x}
 
// Define an error function which prints the stack trace and returns -1
// Note: .Q.sbt formats the backtrace object and 2@ prints to stderr
g:{[x;y] 2@"Error: ",x,"\nBacktrace:\n",.Q.sbt y;-1i}
 
// Try calling the function (wrapped by .Q.trp) with a valid argument
.Q.trp[parseInt;"123";g]
123i
 
// Try calling the function (wrapped by .Q.trp) with an invalid argument
// The error function is called and the stack trace is printed
.Q.trp[parseInt;`hello;g]
Error: type
Backtrace:
  [2]  parseInt:{[x] "I"$x}
                        ^
  [1]  (.Q.trp)
 
  [0]  .Q.trp[parseInt;`hello;g]
       ^
-1i

Note: An alternative is to use Trap At which has syntax @[f;x;e] but you won’t get the backtrace, so it’s better to use .Q.trp.

.[f;args;e] – for n-ary functions

.Q.trp only works for unary functions. For functions with more than one argument, you need to use Trap which has the syntax .[f;args;e]. The error function e does not take any arguments, which means no backtrace available. For example:

1
2
3
4
5
6
7
8
9
// Define a ternary function that sums its arguments
add:{[x;y;z] x+y+z}
 
.[add;1 2 3;{2@"Failed to perform add";-1}]
6
 
.[add;(1;2;`foo);{2@"Failed to perform add\n";-1}]
Failed to perform add
-1

Published on Java Code Geeks with permission by Fahd Shariff, partner at our JCG program. See the original article here: kdb+/q – Try Catch

Opinions expressed by Java Code Geeks contributors are their own.

Fahd Shariff

Fahd is a software engineer working in the financial services industry. He is passionate about technology and specializes in Java application development in distributed environments.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
egor7
egor7
3 years ago
// Define a ternary function that sums its arguments
add:{[x;y;z] x+y+z}

.Q.trp[add .;1 2 3;{2 .Q.sbt y;x}]
6

.Q.trp[add .;(1;2;"foo");{2 .Q.sbt y;x}]
  [2]  add:{[x;y;z] x+y+z}
                       ^
  [1]  (.Q.trp)

  [0]  .Q.trp[add .;(1;2;"foo");{2 .Q.sbt y;x}]
       ^
"type"

in q one can easily use .Q.trp for functions with any number of arguments

Last edited 3 years ago by egor7
Back to top button