Error handling according to the server protocol
Hi, I am currently busy writing C wrapper functions around the public functions from my libBasexCpp library (see https://github.com/BenEngbers/libBasexCpp). In doing so, I discovered an imperfection in that library and an ambiguity in the server protocol. The description of the command protocol states that in the event of an error, the server response consists of {partial result} {error} \01. However, at the bottom of the description of the Query protocol, it is stated that the server response ends with a \01, followed by an error string. In the current implementation, I assumed that all successfully executed requests end with a \00 and that a \01 at the end means an error has occurred. My question is whether this assumption is correct or whether I need to adjust my implementation so that the \01 is followed by the error message? Ben
Hi Ben, The actual protocol framing on error is: {partial result} \00 \01 {error message} \00 Both bytes are present: all results end with a single \00 byte, which indicates that the process was successful. If an error occurs, an additional byte \01 is sent, which is then followed by the error message string. The worked example in the docs makes this concrete [1]: For the query 1, 2+'3', the server sends the partial result "1" terminated with \00, then \01 followed by the error text “Stopped at...”, and finally a closing \00 that terminates the error string itself. The success terminator \00 is always sent; \01 is an additional indicator after it, followed by a \00-terminated error message. What this means for your implementation: • Read until \00: that's the (possibly partial) result. • Don't treat \01 as the end marker; it appears after the \00. • Peek the next byte. If it's \00, success. If it’s \01, read until the next \00 to get the error message. In your current code, treating “ends with \01” as the error signal will work for detection only if you’re reading the whole stream as one blob, but you’ll lose the error message itself and misframe the result boundary. The fix is to consume the error string after the \01. Cheers Christian [1] https://docs.basex.org/main/Server_Protocol#example ________________________________ Von: Ben Engbers via BaseX-Talk <basex-talk@mailman.uni-konstanz.de> Gesendet: Mittwoch, April 29, 2026 12:45:42 AM An: Basex Mail-lijst <basex-talk@mailman.uni-konstanz.de> Betreff: [basex-talk] Error handling according to the server protocol Hi, I am currently busy writing C wrapper functions around the public functions from my libBasexCpp library (see https://github.com/BenEngbers/libBasexCpp). In doing so, I discovered an imperfection in that library and an ambiguity in the server protocol. The description of the command protocol states that in the event of an error, the server response consists of {partial result} {error} \01. However, at the bottom of the description of the Query protocol, it is stated that the server response ends with a \01, followed by an error string. In the current implementation, I assumed that all successfully executed requests end with a \00 and that a \01 at the end means an error has occurred. My question is whether this assumption is correct or whether I need to adjust my implementation so that the \01 is followed by the error message? Ben
Hi Christian, Clear. I'll adapt my code and will experiment with the provided example "query 1, 2+'3'" This brings me to another question; do you have a set of testcases with expected results? I don't know if the testcases in my libBasexTest.cpp cover the complete server protocol. Ben Op 29-04-2026 om 14:04 schreef Christian Grün via BaseX-Talk:
Hi Ben,
The actual protocol framing on error is:
{partial result} \00 \01 {error message} \00
Both bytes are present: all results end with a single \00 byte, which indicates that the process was successful. If an error occurs, an additional byte \01 is sent, which is then followed by the error message string.
The worked example in the docs makes this concrete [1]: For the query 1, 2+'3', the server sends the partial result "1" terminated with \00, then \01 followed by the error text “Stopped at...”, and finally a closing \00 that terminates the error string itself.
Hi Christian, I am still working on the error-handling and in my code these lines handle the errors: And since I am reading the whole Response stream as one single blob, I use the presence of \01 as error-indicator. if (!Success) { debug_dump(Response); ErrorSplit = splitter(Response, (byte)0x01); throw BasexExecuteException(ErrorString); } else { ... These are the results for 2 eror-cases 1. Try executing Session.Create("TestCppClient") when this database is opened in BasexGUI: 44 61 74 61 62 61 73 65 20 27 54 65 73 74 43 70 70 43 6c 69 65 6e 74 27 20 69 73 20 6f 70 65 6e 65 64 20 62 79 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73 73 2e 00 01 Database 'TestCppClient' is opened by another process.| ErrorSplit.size(): 1 2: Evaluate Q_Object = Session.Query("1, '2'+3"); Q_Object -> Execute(); 00 01 53 74 6f 70 70 65 64 20 61 74 20 2e 2c 20 31 2f 38 3a 0a 5b 58 50 54 59 30 30 30 34 5d 20 41 72 69 74 68 6d 65 74 69 63 73 20 6e 6f 74 20 64 65 66 69 6e 65 64 20 66 6f 72 20 78 73 3a 73 74 72 69 6e 67 20 61 6e 64 20 78 73 3a 69 6e 74 65 67 65 72 3a 20 22 32 22 20 2b 20 33 2e 00 |Stopped at ., 1/8: [XPTY0004] Arithmetics not defined for xs:string and xs:integer: "2" + 3.| ErrorSplit.size(): 2 In case 1 I would have expected that there would be a trailing \00 after the \01, indicating that there is no specific error message. Is it correct that the message is considered as a (partial) result? In caase 2 I would have expected that the vector would begin with \00 (=empty partial result) \00 \01 Is it correct that the trailing bytes form the error-message? It is easy to let my code handle the 2 different cases but I want to be sure that a trailing \01 implies that there is no specific error message. I still find it a bit confusing that the documentation mentions 2 different error strategies: - Command Protocol : { partial result } {error} \01 - Query Command Protocol: If an error occurs, an additional byte \01 is sent, which is then followed by the error message string. Cheers, Ben Op 29-04-2026 om 14:04 schreef Christian Grün via BaseX-Talk:
Hi Ben,
The actual protocol framing on error is:
{partial result} \00 \01 {error message} \00
Both bytes are present: all results end with a single \00 byte, which indicates that the process was successful. If an error occurs, an additional byte \01 is sent, which is then followed by the error message string.
The worked example in the docs makes this concrete [1]: For the query 1, 2+'3', the server sends the partial result "1" terminated with \00, then \01 followed by the error text “Stopped at...”, and finally a closing \00 that terminates the error string itself.
The success terminator \00 is always sent; \01 is an additional indicator after it, followed by a \00-terminated error message.
What this means for your implementation:
• Read until \00: that's the (possibly partial) result. • Don't treat \01 as the end marker; it appears after the \00. • Peek the next byte. If it's \00, success. If it’s \01, read until the next \00 to get the error message.
In your current code, treating “ends with \01” as the error signal will work for detection only if you’re reading the whole stream as one blob, but you’ll lose the error message itself and misframe the result boundary. The fix is to consume the error string after the \01.
Cheers Christian
[1] https://docs.basex.org/main/Server_Protocol#example <https:// docs.basex.org/main/Server_Protocol#example>
Hi Ben,
Is it correct that the message is considered as a (partial) result?
No. In Command Protocol, the bytes before \00 \01 are the error message, not a partial result. A partial result would precede it (empty here).
Is it correct that the trailing bytes form the error message?
Yes, in the Query protocol: \00 \01 {error text} \00.
Does a trailing \01 imply no specific error message?
In Command Protocol: a bare \00 \01 (nothing between the last \00 before \01) means the error string is empty. But \01 is always the last byte. There’s never anything after it. In Query Protocol: \01 is never trailing; it’s always followed by the error string (possibly empty: \01 \00). Cheers, Christian
participants (2)
-
Ben Engbers -
Christian Grün