Interprocess Communication (IPC) · Opening Connections (hopen) · Practice Question
Implement Error Handling on hopen
Question
How would you implement error handling on an hopen call so that a connection failure — such as a timeout — is caught gracefully rather than crashing the calling process?
Solution
h:@[hopen;(`::5002;10000);{[err] show err}]If the connection succeeds, h holds the integer handle as normal.
If it fails — for example because nothing is listening, or the timeout expires — the error string is passed to the handler function instead, which here prints it to the screen. If nothing is listening on port 5002, for instance, it prints:
"hop. OS reports: Connection refused"(and if the process is listening but doesn't respond within 10 seconds, it prints "timeout"). Note that h is then whatever the handler returned — here the result of show, the generic null — so in real code have the handler return something you can test, as below.
Explanation
@[f;x;e] is q's protected evaluation form: call f[x], and if a signal is raised, call e with the error string instead of propagating the error to the caller. Applied to hopen:
@[hopen; descriptor; errorHandler]descriptor— the connection target, exactly as you would pass to a plainhopencall (a symbol, an integer port, or a 2-item list with a timeout)errorHandler— a function that receives the error string and decides what to do with it
Common patterns for the handler:
/ Log and return a null handle
h:@[hopen;(`::5002;10000);{[e] -1"Connection failed: ",e; 0Ni}]
/ Return a sentinel so the caller can test
h:@[hopen;(`::5002;10000);{[e] `$"FAILED"}]
/ Retry logic — attempt up to 3 times with a 1-second pause
connectWithRetry:{[desc]
h:0Ni;
do[3; h:@[hopen;desc;{0Ni}]; if[not null h; :h]; system"sleep 1"];
h
}In production kdb+ systems — especially feed handlers and gateways that connect to multiple downstream processes on startup — protected hopen is standard practice. An uncaught error from a bare hopen aborts whatever was running — for example, the rest of a start-up script is not executed — so wrapping it in @ is the safe default whenever the target process might not be available immediately.