From 9346ae9062cac650251579029db1c679d1c332bc Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields (OpenClaw)" Date: Fri, 15 May 2026 14:45:19 +0000 Subject: [PATCH] fix: make transaction reset best effort --- n_request.c | 18 ++++-------------- test/src/NoteTransaction_test.cpp | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/n_request.c b/n_request.c index c774720a..a3e75e99 100644 --- a/n_request.c +++ b/n_request.c @@ -528,22 +528,12 @@ J *_noteTransactionShouldLock(J *req, bool lockNotecard) _LockNote(); } - // If a reset of the I/O interface is required for any reason, do it now. + // If a reset of the I/O interface is required for any reason, make a best + // effort to resynchronize before continuing with the transaction. if (resetRequired) { NOTE_C_LOG_DEBUG("Resetting Notecard I/O Interface..."); - if ((resetRequired = !_Reset())) { - if (lockNotecard) { - _UnlockNote(); - } - _Free(json); - _TransactionStop(); - const char *errStr = ERRSTR("failed to reset Notecard interface {io}", c_iobad); - if (cmdFound) { - NOTE_C_LOG_ERROR(errStr); - return NULL; - } - return _errDoc(id, errStr); - } + _Reset(); + resetRequired = false; } // If we're performing retries, this is where we come back to diff --git a/test/src/NoteTransaction_test.cpp b/test/src/NoteTransaction_test.cpp index ee64e1d3..c4eec44a 100644 --- a/test/src/NoteTransaction_test.cpp +++ b/test/src/NoteTransaction_test.cpp @@ -505,7 +505,7 @@ SCENARIO("NoteTransaction") JDelete(req); } - SECTION("A reset is required and it fails") { + SECTION("A reset is required and it fails before a command") { J *req = NoteNewCommand("note.add"); REQUIRE(req != NULL); NoteResetRequired(); @@ -515,31 +515,34 @@ SCENARIO("NoteTransaction") J *resp = NoteTransaction(req); REQUIRE(_noteHardReset_fake.call_count == 1); - // The transaction shouldn't be attempted if reset failed. - CHECK(_noteJSONTransaction_fake.call_count == 0); + // Reset is best effort; the transaction is still attempted. + CHECK(_noteJSONTransaction_fake.call_count == 1); + CHECK(resetRequired == false); - // The response should be null if reset failed. - CHECK(resp == NULL); + // Commands return an empty response object after the transaction attempt. + CHECK(resp != NULL); JDelete(req); + JDelete(resp); } - SECTION("A reset is required and it fails") { + SECTION("A reset is required and it fails before a request") { J *req = NoteNewRequest("note.add"); REQUIRE(req != NULL); NoteResetRequired(); // Force NoteReset failure. _noteHardReset_fake.return_val = false; + _noteJSONTransaction_fake.custom_fake = _noteJSONTransactionValid; J *resp = NoteTransaction(req); REQUIRE(_noteHardReset_fake.call_count == 1); - // The transaction shouldn't be attempted if reset failed. - CHECK(_noteJSONTransaction_fake.call_count == 0); + // Reset is best effort; the transaction is still attempted. + CHECK(_noteJSONTransaction_fake.call_count == 1); + CHECK(resetRequired == false); - // The response should be null if reset failed. CHECK(resp != NULL); - CHECK(NoteResponseError(resp)); + CHECK(!NoteResponseError(resp)); JDelete(req); JDelete(resp);