Skip to content

JavaScript SDK: fix config read errors silently degrading to an empty config (KSM-1266) - #1132

Open
stas-schaller wants to merge 1 commit into
feature/KSM-1263-js-config-file-permissionsfrom
feature/KSM-1266-js-config-read-error-handling
Open

JavaScript SDK: fix config read errors silently degrading to an empty config (KSM-1266)#1132
stas-schaller wants to merge 1 commit into
feature/KSM-1263-js-config-file-permissionsfrom
feature/KSM-1266-js-config-read-error-handling

Conversation

@stas-schaller

@stas-schaller stas-schaller commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Summary

JavaScript SDK: fixes localConfigStorage treating every config-read failure as "no config yet."

Changes

Fixed

  • readStorage caught every exception from reading or parsing the config file and returned an empty config, masking permission errors and malformed JSON as a fresh start. Only a missing file (ENOENT) is treated that way now; everything else throws a KeeperError. (KSM-1266)

Testing

cd sdk/javascript/packages/core && npm test -- test/localConfigStorage.test.ts

Breaking Changes

None as a public API change, but a behavior change: localConfigStorage(configName) can now throw KeeperError for a config file that exists but is unreadable or malformed, where it previously started fresh silently. Callers that only expected the missing-file case are unaffected.

Related Issues

  • Jira: KSM-1266

… empty config (KSM-1266)

localConfigStorage's readStorage treated every read failure as "no
config yet," including permission errors and malformed JSON. Only a
missing file (ENOENT) is treated that way now; everything else throws
a KeeperError.
@stas-schaller stas-schaller changed the title fix(javascript): unreadable or corrupt config degrades silently to an empty config (KSM-1266) JavaScript SDK: fix config read errors silently degrading to an empty config (KSM-1266) Aug 26, 2026

@mgallego-keeper mgallego-keeper left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

Correct, well-targeted fix for KSM-1266. JSON.parse's SyntaxError has no .code property, so malformed JSON correctly falls through to the KeeperError branch rather than being mistaken for ENOENT; verified this holds. The three new tests (missing file, unreadable file, malformed JSON) match the intended behavior exactly, and the PR body's own disclosure of the behavior change (localConfigStorage can now throw where it previously started fresh silently) is accurate and, in my view, the right tradeoff: masking a permission error or corrupt config as "no config yet" is worse than a loud failure. One robustness note on the new tests below, not blocking.

Notes

The "unreadable config file" test assumes a non-root process

chmodSync(configPath, 0o000) only blocks read access for a non-root user. If this suite is ever run as root (a common default in Docker-based Node images or some CI containers), fs.readFileSync will still succeed despite mode 0, the file will parse as valid empty JSON, and readStorage won't throw at all, so this test would fail to exercise the code path it's meant to cover (and would fail outright, since the toThrow(KeeperError) assertion would not be satisfied). Not a defect in the production code, just a latent assumption in this specific test. Worth a comment noting the non-root assumption, or skipping the test when process.getuid?.() === 0, so a future root-run CI environment doesn't quietly lose this coverage.

Minor style nit

catch (e: Error | any) is unusual TypeScript; Error | any collapses to plain any during type resolution (confirmed this compiles cleanly under strict: true), so it reads as more specific than it actually is. Purely cosmetic, no functional difference from catch (e: any).

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.

2 participants