Skip to content

fix(sqlite-native): restore kv error hook#4635

Open
NathanFlurry wants to merge 1 commit into04-12-perf_sqlite-native_avoid_cloning_cached_read_chunksfrom
04-12-fix_sqlite-native_restore_kv_error_hook
Open

fix(sqlite-native): restore kv error hook#4635
NathanFlurry wants to merge 1 commit into04-12-perf_sqlite-native_avoid_cloning_cached_read_chunksfrom
04-12-fix_sqlite-native_restore_kv_error_hook

Conversation

@NathanFlurry
Copy link
Copy Markdown
Member

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Copy link
Copy Markdown
Member Author

NathanFlurry commented Apr 13, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@claude
Copy link
Copy Markdown

claude bot commented Apr 13, 2026

PR Review: fix(sqlite-native): restore kv error hook

Overview

This PR restores the KV error hook in the native SQLite VFS layer and improves error propagation from native Rust storage failures to the JavaScript layer. The changes enable richer error messages when an actor's KV store becomes unavailable (e.g., during actor shutdown).


Positive Changes

  • Error propagation chain is well-designed: Rust VFS captures KV error, stores it in VfsContext::last_error, kv_vfs_get_last_error exposes it to SQLite, NativeDatabase::take_last_kv_error exposes it to the NAPI layer, and JS wrapNativeStorageError wraps it with a user-friendly message. Clean layered design.
  • notGlobal: config.notGlobal ?? false: Good defensive fix preventing undefined from leaking in place of false.
  • read_cache.as_ref().and_then(...) and value.as_deref(): Correctness fixes, presumably needed after read_cache became Option<...>.
  • sqlite_error_message helper: Improves open/pragma error messages with the actual SQLite error string instead of just the error code.
  • Tracing in on_error: Correctly uses structured tracing::error! per project conventions.

Issues and Suggestions

kv_vfs_get_last_error truncation not signalled (vfs.rs)

Per the SQLite VFS spec, xGetLastError should return non-zero when the message is truncated (bytes.len() > max_len). The current implementation always returns 0 even when truncated. Low severity since SQLite treats this as a hint, but worth fixing for spec compliance.


Implicit fall-through after wrapNativeStorageError (wrapper.js)

In all three try-catch blocks, wrapNativeStorageError always throws so runtime behavior is correct. However, static analysers see an implicit undefined return after the call. Consider making the never-returning intent explicit by having wrapNativeStorageError return the Error instead of throwing it internally, and using throw wrapNativeStorageError(nativeDb, error) at the call sites.


KvVfs::take_last_kv_error missing safety comment (vfs.rs ~line 1270)

The unsafe block dereferences ctx_ptr with no safety comment. A brief comment (e.g. // Safety: ctx_ptr is valid for the lifetime of KvVfs) would follow standard practice for unsafe blocks in this codebase.


Clear-on-success could race with JS error handling (vfs.rs)

clear_last_error is called after every successful KV operation. SQLite can internally make cleanup calls after an I/O error, so a KV failure followed by a successful cleanup call erases the error before the JS catch block calls takeLastKvError. The window is small in practice, but it is a real race. Consider only consuming the error at JS exception-catch time rather than clearing it on every success.


No tests

The PR checklist leaves the test box unchecked. Given this is a non-trivial error-path change across the Rust/NAPI/JS boundary, a test that triggers a KV failure and asserts the resulting JS error message contains the expected text would be valuable.

@NathanFlurry NathanFlurry force-pushed the 04-12-perf_sqlite-native_avoid_cloning_cached_read_chunks branch from ceec0d4 to ff117f9 Compare April 13, 2026 05:38
@NathanFlurry NathanFlurry force-pushed the 04-12-fix_sqlite-native_restore_kv_error_hook branch from 6eac78f to 4e380c8 Compare April 13, 2026 05:38
@NathanFlurry NathanFlurry force-pushed the 04-12-perf_sqlite-native_avoid_cloning_cached_read_chunks branch from ff117f9 to e25c1b6 Compare April 13, 2026 05:50
@NathanFlurry NathanFlurry force-pushed the 04-12-fix_sqlite-native_restore_kv_error_hook branch 2 times, most recently from 7fbbf37 to fe8cf4f Compare April 13, 2026 07:03
@NathanFlurry NathanFlurry force-pushed the 04-12-perf_sqlite-native_avoid_cloning_cached_read_chunks branch from e25c1b6 to 532364f Compare April 13, 2026 07:03
@NathanFlurry NathanFlurry force-pushed the 04-12-fix_sqlite-native_restore_kv_error_hook branch from fe8cf4f to 2be63d0 Compare April 13, 2026 21:07
@NathanFlurry NathanFlurry force-pushed the 04-12-perf_sqlite-native_avoid_cloning_cached_read_chunks branch from 532364f to 22df032 Compare April 13, 2026 21:07
@NathanFlurry NathanFlurry marked this pull request as ready for review April 14, 2026 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant