mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
🛠️ feat: Add Config Validation Bypass & Improve Error Handling (#10733)
* fix: exit on invalid configuration and add bypass validation warning * test: enhance loadCustomConfig tests for exit behavior on invalid config
This commit is contained in:
parent
7080c61525
commit
6aa696b74f
2 changed files with 54 additions and 13 deletions
|
|
@ -85,7 +85,6 @@ Please specify a correct \`imageOutputType\` value (case-sensitive).
|
||||||
let errorMessage = `Invalid custom config file at ${configPath}:
|
let errorMessage = `Invalid custom config file at ${configPath}:
|
||||||
${JSON.stringify(result.error, null, 2)}`;
|
${JSON.stringify(result.error, null, 2)}`;
|
||||||
|
|
||||||
if (i === 0) {
|
|
||||||
logger.error(errorMessage);
|
logger.error(errorMessage);
|
||||||
const speechError = result.error.errors.find(
|
const speechError = result.error.errors.find(
|
||||||
(err) =>
|
(err) =>
|
||||||
|
|
@ -101,10 +100,17 @@ If you're getting this error, please refer to the latest documentation:
|
||||||
https://www.librechat.ai/docs/configuration/stt_tts`);
|
https://www.librechat.ai/docs/configuration/stt_tts`);
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
if (process.env.CONFIG_BYPASS_VALIDATION === 'true') {
|
||||||
|
logger.warn(
|
||||||
|
'CONFIG_BYPASS_VALIDATION is enabled. Continuing with default configuration despite validation errors.',
|
||||||
|
);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
logger.error(
|
||||||
|
'Exiting due to invalid configuration. Set CONFIG_BYPASS_VALIDATION=true to bypass this check.',
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
} else {
|
} else {
|
||||||
if (printConfig) {
|
if (printConfig) {
|
||||||
logger.info('Custom config file loaded:');
|
logger.info('Custom config file loaded:');
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,25 @@ const { logger } = require('@librechat/data-schemas');
|
||||||
const loadCustomConfig = require('./loadCustomConfig');
|
const loadCustomConfig = require('./loadCustomConfig');
|
||||||
|
|
||||||
describe('loadCustomConfig', () => {
|
describe('loadCustomConfig', () => {
|
||||||
|
const originalExit = process.exit;
|
||||||
|
const mockExit = jest.fn((code) => {
|
||||||
|
throw new Error(`process.exit called with "${code}"`);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
process.exit = mockExit;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
process.exit = originalExit;
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
|
// Re-apply the exit mock implementation after resetAllMocks
|
||||||
|
mockExit.mockImplementation((code) => {
|
||||||
|
throw new Error(`process.exit called with "${code}"`);
|
||||||
|
});
|
||||||
delete process.env.CONFIG_PATH;
|
delete process.env.CONFIG_PATH;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -94,20 +111,38 @@ describe('loadCustomConfig', () => {
|
||||||
it('should return null and log if config schema validation fails', async () => {
|
it('should return null and log if config schema validation fails', async () => {
|
||||||
const invalidConfig = { invalidField: true };
|
const invalidConfig = { invalidField: true };
|
||||||
process.env.CONFIG_PATH = 'invalidConfig.yaml';
|
process.env.CONFIG_PATH = 'invalidConfig.yaml';
|
||||||
|
process.env.CONFIG_BYPASS_VALIDATION = 'true';
|
||||||
loadYaml.mockReturnValueOnce(invalidConfig);
|
loadYaml.mockReturnValueOnce(invalidConfig);
|
||||||
|
|
||||||
const result = await loadCustomConfig();
|
const result = await loadCustomConfig();
|
||||||
|
|
||||||
expect(result).toBeNull();
|
expect(result).toBeNull();
|
||||||
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
|
'CONFIG_BYPASS_VALIDATION is enabled. Continuing with default configuration despite validation errors.',
|
||||||
|
);
|
||||||
|
delete process.env.CONFIG_BYPASS_VALIDATION;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call process.exit(1) when config validation fails without bypass', async () => {
|
||||||
|
const invalidConfig = { invalidField: true };
|
||||||
|
process.env.CONFIG_PATH = 'invalidConfig.yaml';
|
||||||
|
loadYaml.mockReturnValueOnce(invalidConfig);
|
||||||
|
|
||||||
|
await expect(loadCustomConfig()).rejects.toThrow('process.exit called with "1"');
|
||||||
|
expect(logger.error).toHaveBeenCalledWith(
|
||||||
|
'Exiting due to invalid configuration. Set CONFIG_BYPASS_VALIDATION=true to bypass this check.',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle and return null on YAML parse error for a string response from remote', async () => {
|
it('should handle and return null on YAML parse error for a string response from remote', async () => {
|
||||||
process.env.CONFIG_PATH = 'http://example.com/config.yaml';
|
process.env.CONFIG_PATH = 'http://example.com/config.yaml';
|
||||||
|
process.env.CONFIG_BYPASS_VALIDATION = 'true';
|
||||||
axios.get.mockResolvedValue({ data: 'invalidYAMLContent' });
|
axios.get.mockResolvedValue({ data: 'invalidYAMLContent' });
|
||||||
|
|
||||||
const result = await loadCustomConfig();
|
const result = await loadCustomConfig();
|
||||||
|
|
||||||
expect(result).toBeNull();
|
expect(result).toBeNull();
|
||||||
|
delete process.env.CONFIG_BYPASS_VALIDATION;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the custom config object for a valid remote config file', async () => {
|
it('should return the custom config object for a valid remote config file', async () => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue