Skip to content

Commit

Permalink
base_config: Don't throw if loaded config file is empty
Browse files Browse the repository at this point in the history
  • Loading branch information
scottnonnenberg-signal committed Oct 25, 2021
1 parent 53bc13a commit be862af
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 9 deletions.
25 changes: 18 additions & 7 deletions app/base_config.ts
Expand Up @@ -13,6 +13,9 @@ export type ConfigType = {
set: (keyPath: string, value: unknown) => void;
get: (keyPath: string) => unknown;
remove: () => void;

// Test-only
_getCachedValue: () => InternalConfigType | undefined;
};

export function start(
Expand All @@ -21,10 +24,11 @@ export function start(
options?: { allowMalformedOnStartup?: boolean }
): ConfigType {
let cachedValue: InternalConfigType | undefined;
let incomingJson: string | undefined;

try {
const text = readFileSync(targetPath, ENCODING);
cachedValue = JSON.parse(text);
incomingJson = readFileSync(targetPath, ENCODING);
cachedValue = incomingJson ? JSON.parse(incomingJson) : undefined;
console.log(`config/get: Successfully read ${name} config file`);

if (!cachedValue) {
Expand All @@ -38,9 +42,15 @@ export function start(
throw error;
}

console.log(
`config/get: Did not find ${name} config file, cache is now empty object`
);
if (incomingJson) {
console.log(
`config/get: ${name} config file was malformed, starting afresh`
);
} else {
console.log(
`config/get: Did not find ${name} config file (or it was empty), cache is now empty object`
);
}
cachedValue = Object.create(null);
}

Expand All @@ -55,8 +65,8 @@ export function start(

set(cachedValue, keyPath, value);
console.log(`config/set: Saving ${name} config to disk`);
const text = JSON.stringify(cachedValue, null, ' ');
writeFileSync(targetPath, text, ENCODING);
const outgoingJson = JSON.stringify(cachedValue, null, ' ');
writeFileSync(targetPath, outgoingJson, ENCODING);
}

function remove(): void {
Expand All @@ -69,5 +79,6 @@ export function start(
set: ourSet,
get: ourGet,
remove,
_getCachedValue: () => cachedValue,
};
}
3 changes: 1 addition & 2 deletions app/main.ts
Expand Up @@ -31,7 +31,6 @@ import * as GlobalErrors from './global_errors';
import { setup as setupSpellChecker } from './spell_check';
import { redactAll, addSensitivePath } from '../ts/util/privacy';
import { consoleLogger } from '../ts/util/consoleLogger';
import { remove as removeUserConfig } from './user_config';

import './startup_config';

Expand Down Expand Up @@ -1318,7 +1317,7 @@ const onDatabaseError = async (error: string) => {
clipboard.writeText(`Database startup error:\n\n${redactAll(error)}`);
} else {
await sql.removeDB();
removeUserConfig();
userConfig.remove();
app.relaunch();
}

Expand Down
71 changes: 71 additions & 0 deletions ts/test-node/app/base_config_test.ts
@@ -0,0 +1,71 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only

import { tmpdir } from 'os';
import { writeFileSync, unlinkSync } from 'fs';

import { v4 as generateGuid } from 'uuid';
import { assert } from 'chai';

import { start } from '../../../app/base_config';

describe('base_config', () => {
let targetFile: string | undefined;

function getNewPath() {
return `${tmpdir()}/${generateGuid()}.txt`;
}

afterEach(() => {
if (targetFile) {
unlinkSync(targetFile);
}
});

it('does not throw if file is missing', () => {
const missingFile = getNewPath();
const { _getCachedValue } = start('test', missingFile);

assert.deepEqual(_getCachedValue(), Object.create(null));
});

it('successfully loads config file', () => {
targetFile = getNewPath();

const config = { a: 1, b: 2 };
writeFileSync(targetFile, JSON.stringify(config));
const { _getCachedValue } = start('test', targetFile);

assert.deepEqual(_getCachedValue(), config);
});

it('throws if file is malformed', () => {
targetFile = getNewPath();

writeFileSync(targetFile, '{{ malformed JSON');

const fileForClosure = targetFile;
assert.throws(() => start('test', fileForClosure));
});

it('does not throw if file is empty', () => {
targetFile = getNewPath();

writeFileSync(targetFile, '');

const { _getCachedValue } = start('test', targetFile);

assert.deepEqual(_getCachedValue(), Object.create(null));
});

it('does not throw if file is malformed, with allowMalformedOnStartup', () => {
targetFile = getNewPath();

writeFileSync(targetFile, '{{ malformed JSON');
const { _getCachedValue } = start('test', targetFile, {
allowMalformedOnStartup: true,
});

assert.deepEqual(_getCachedValue(), Object.create(null));
});
});

0 comments on commit be862af

Please sign in to comment.