Skip to content

Commit 35fa52c

Browse files
committed
fix(codec): parse WebSocket responses independent of JSON field order
1 parent b4cbc22 commit 35fa52c

2 files changed

Lines changed: 37 additions & 16 deletions

File tree

‎libsql-hrana-codec/src/main/java/com/github/magnusp/libsql/hrana/codec/DirectHranaJsonCodec.java‎

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -689,31 +689,40 @@ public WsServerMsg deserialize(byte[] payload) throws IOException {
689689
}
690690

691691
private WsResponse parseWsResponse(FastJsonParser p) throws IOException {
692+
// JSON object field order is not significant, so find the type before reading the payload.
693+
int start = p.pos;
692694
p.expectObjectStart();
693695
String type = null;
694-
StmtResult stmtResult = null;
695-
BatchResult batchResult = null;
696-
697696
while (!p.checkObjectEnd()) {
698697
String field = p.nextFieldName();
699-
switch (field) {
700-
case "type" -> type = p.nextString();
701-
case "result" -> {
702-
if ("execute".equals(type)) {
703-
stmtResult = parseStmtResult(p);
704-
} else if ("batch".equals(type)) {
705-
batchResult = parseBatchResult(p);
706-
} else {
707-
p.skipValue();
708-
}
709-
}
710-
default -> p.skipValue();
698+
if ("type".equals(field)) {
699+
type = p.nextString();
700+
} else {
701+
p.skipValue();
711702
}
712703
}
713-
714704
if (type == null) {
715705
throw new IOException("WebSocket response missing type field");
716706
}
707+
708+
p.pos = start;
709+
p.expectObjectStart();
710+
StmtResult stmtResult = null;
711+
BatchResult batchResult = null;
712+
while (!p.checkObjectEnd()) {
713+
String field = p.nextFieldName();
714+
if ("result".equals(field)) {
715+
if ("execute".equals(type)) {
716+
stmtResult = parseStmtResult(p);
717+
} else if ("batch".equals(type)) {
718+
batchResult = parseBatchResult(p);
719+
} else {
720+
p.skipValue();
721+
}
722+
} else {
723+
p.skipValue();
724+
}
725+
}
717726
return switch (type) {
718727
case "open_stream" -> WsResponse.OpenStream.INSTANCE;
719728
case "close_stream" -> WsResponse.CloseStream.INSTANCE;

‎libsql-hrana-codec/src/test/java/com/github/magnusp/libsql/hrana/codec/DirectHranaWsJsonCodecTest.java‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,18 @@ void deserializesBatchResponse() throws IOException {
160160
.isEqualTo(new WsServerMsg.ResponseOk(12, new WsResponse.Batch(expected)));
161161
}
162162

163+
@Test
164+
void deserializesExecuteResponseRegardlessOfFieldOrder() throws IOException {
165+
String json = """
166+
{"response":{"result":{"cols":[],"rows":[],"affected_row_count":0},
167+
"type":"execute"},"request_id":14,"type":"response_ok"}""";
168+
169+
StmtResult expected = new StmtResult(List.of(), List.of(), 0, null);
170+
171+
assertThat(codec.deserialize(utf8(json)))
172+
.isEqualTo(new WsServerMsg.ResponseOk(14, new WsResponse.Execute(expected)));
173+
}
174+
163175
@Test
164176
void deserializesResponseError() throws IOException {
165177
assertThat(codec.deserialize(utf8(

0 commit comments

Comments
 (0)