Fix: add null check for vault file in JSONFileVault watcher initialization#110
Fix: add null check for vault file in JSONFileVault watcher initialization#110SyedZawwarAhmed wants to merge 1 commit intoSmythOS:devfrom
Conversation
…ation Signed-off-by: SyedZawwarAhmed <zawwar.ahmed12@gmail.com>
WalkthroughA guard was added to JSONFileVault.initFileWatcher to detect a missing vault file. When no vault file is configured, it logs a warning and exits without creating a chokidar watcher. Existing behavior for watcher setup and change handling remains unchanged when a vault file is present. Changes
Sequence Diagram(s)sequenceDiagram
participant App as App
participant JSONVault as JSONFileVault
participant FS as chokidar (FS Watcher)
App->>JSONVault: initFileWatcher()
alt vaultFile is missing
JSONVault->>JSONVault: log warning
JSONVault-->>App: return (no watcher)
else vaultFile is present
JSONVault->>FS: create watcher on vaultFile
FS-->>JSONVault: change event
JSONVault->>JSONVault: handle change (reload/update)
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/core/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts (3)
41-44: Potential crash: fetchVaultData called with null/undefined vaultFile.
If findVaultFile returns null/undefined, fs.existsSync(null) inside fetchVaultData will throw before your new guard runs.Apply this diff to guard the constructor call:
this.vaultFile = this.findVaultFile(_settings.file); - this.fetchVaultData(this.vaultFile, _settings); + if (this.vaultFile) { + this.fetchVaultData(this.vaultFile, _settings); + } else { + this.vaultData = {}; + } this.initFileWatcher();
46-72: findVaultFile can call fs.existsSync with undefined/null and returns null into a field typed as string.
Strengthen types and guards to avoid TypeErrors and keep types honest.Apply this diff:
- private findVaultFile(vaultFile) { - let _vaultFile = vaultFile; - - if (fs.existsSync(_vaultFile)) { + private findVaultFile(vaultFile?: string | null): string | null { + const _vaultFile = vaultFile ?? null; + + if (_vaultFile && fs.existsSync(_vaultFile)) { return _vaultFile; } - console.warn('Vault file not found in:', _vaultFile); + if (_vaultFile) { + console.warn('Vault file not found in:', _vaultFile); + } else { + console.warn('No vault file configured in JSONFileVaultConfig.file'); + } @@ - _vaultFile = findSmythPath('.sre/vault.json', (dir, success, nextDir) => { + const alternate = findSmythPath('.sre/vault.json', (dir, success, nextDir) => { if (!success) { console.warn('Vault file not found in:', nextDir); } }); - if (fs.existsSync(_vaultFile)) { - console.warn('Using alternative vault file found in : ', _vaultFile); - return _vaultFile; + if (alternate && fs.existsSync(alternate)) { + console.warn('Using alternative vault file found in : ', alternate); + return alternate; } console.warn('!!! All attempts to find the vault file failed !!!'); console.warn('!!! Will continue without vault !!!'); console.warn('!!! Many features might not work !!!'); return null; }Also update the field type at declaration (Line 32):
- private vaultFile: string; + private vaultFile: string | null;
160-201: fetchVaultData assumes a non-null path; will throw on null.
Make the parameter nullable and no-op when absent.Apply this diff:
- private fetchVaultData(vaultFile: string, _settings: JSONFileVaultConfig) { - if (fs.existsSync(vaultFile)) { + private fetchVaultData(vaultFile: string | null, _settings: JSONFileVaultConfig) { + if (!vaultFile) { + console.warn('No vault file provided; skipping data load'); + this.vaultData = this.vaultData || {}; + return; + } + if (fs.existsSync(vaultFile)) { try { if (_settings.fileKey && fs.existsSync(_settings.fileKey)) {
🧹 Nitpick comments (5)
packages/core/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts (5)
208-216: Add watcher error handling for robustness.
Capture chokidar errors to aid diagnosis; optional but low-cost.Apply this diff:
this.watcher = chokidar.watch(this.vaultFile, { persistent: false, // Don't keep the process running ignoreInitial: true, }); + this.watcher.on('error', (err) => { + console.error('Vault watcher error:', err); + }); + this.watcher.on('change', () => { this.fetchVaultData(this.vaultFile, this._settings); });
218-224: Await watcher.close() to ensure clean shutdown.
close() returns a Promise; awaiting avoids dangling handles in tests/CLI.Apply this diff:
public async stop() { super.stop(); if (this.watcher) { - this.watcher.close(); + await this.watcher.close(); this.watcher = null; } }
21-25: Type accuracy: vaultFile, watcher, and config types.
Minor consistency tweaks make strict TS happier.Apply this diff:
export type JSONFileVaultConfig = { - file?: string; + file?: string | null; fileKey?: string; shared?: string; }; @@ - private watcher: chokidar.FSWatcher | null = null; + private watcher: chokidar.FSWatcher | null = null;(Only change is making file nullable; watcher line included for context.)
Also applies to: 31-34
200-201: Index is built but never read.
If intentional, add a TODO; else remove to save memory.I can follow up with a removal PR if unused.
1-225: Add a regression test for “no vault file” scenario.
Prevents future crashes when config omits file and ensures watcher isn’t created.I can add a unit test that constructs JSONFileVault with { file: null } (and/or undefined), asserting no exception, no watcher, and vaultData is {}. Want me to open a test PR?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/core/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts(1 hunks)
🔇 Additional comments (1)
packages/core/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts (1)
204-207: Good guard—prevents watcher init when vault path is absent.
This avoids chokidar errors on falsy paths and aligns with the PR goal.
📝 Description
Adds a safety check to prevent JSONFileVault file watcher initialization when the vault file is not there. This prevents potential runtime errors and adds appropriate warning logging for debugging purposes.
🔗 Related Issues
🔧 Type of Change
✅ Checklist
Summary by CodeRabbit