Description
Currently, ConfigService only validates if mandatory fields are present and matches basic types. It lacks the ability to perform custom logic-based validation (e.g., checking if a numeric value is non-zero when used as a denominator).
While 1c4b168 introduced a specific "bandage" validation for MIRROR_NODE_MAX_LOGS_PER_TIMESTAMP_SLICE inside the ConfigService constructor, the service should be enhanced to support a first-class, generic custom validation mechanism.
Proposed Solution
An approach is to add a validation function to the ConfigProperty interface in globalConfig.ts. This function will be executed during the ConfigService initialization after type casting has occurred.
Technical Implementation
1. Update ConfigProperty Interface
Add an optional validation property to the interface:
export interface ConfigProperty {
type: 'string' | 'number' | 'boolean' | 'strArray' | 'numArray';
required: boolean;
defaultValue: ...;
validation?: (value: any) => boolean | string; // Returns true or an error message
}
2. Implement Validation Logic in ValidationService
Add a static validate method that iterates through GlobalConfig.ENTRIES and executes the validation function if it exists:
static validate(castedEnvs: NodeJS.Dict<any>): void {
Object.entries(GlobalConfig.ENTRIES).forEach(([entryName, entryInfo]) => {
const value = castedEnvs[entryName];
if (entryInfo.validation && value !== undefined && value !== null) {
const result = entryInfo.validation(value);
if (result !== true) {
throw new Error(`Configuration error: ${result || `${entryName} validation failed`}`);
}
}
});
}
3. Integrate with ConfigService
Invoke ValidationService.validate(this.envs) in the ConfigService constructor after ValidationService.typeCasting(process.env).
4. Define Validation for MIRROR_NODE_MAX_LOGS_PER_TIMESTAMP_SLICE (and potentially other configurations)
MIRROR_NODE_MAX_LOGS_PER_TIMESTAMP_SLICE: {
type: 'number',
required: false,
defaultValue: 100,
validation: (value: number) => value >= 1 || 'MIRROR_NODE_MAX_LOGS_PER_TIMESTAMP_SLICE must be 1 or greater (used as denominator)',
}
Impact
- Prevents runtime crashes (e.g. division by zero & potentially others).
- Improves developer experience with clear configuration error messages.
- Aligns with SOLID principles by decentralizing validation logic into the configuration metadata.
Description
Currently,
ConfigServiceonly validates if mandatory fields are present and matches basic types. It lacks the ability to perform custom logic-based validation (e.g., checking if a numeric value is non-zero when used as a denominator).While 1c4b168 introduced a specific "bandage" validation for
MIRROR_NODE_MAX_LOGS_PER_TIMESTAMP_SLICEinside theConfigServiceconstructor, the service should be enhanced to support a first-class, generic custom validation mechanism.Proposed Solution
An approach is to add a
validationfunction to theConfigPropertyinterface inglobalConfig.ts. This function will be executed during theConfigServiceinitialization after type casting has occurred.Technical Implementation
1. Update
ConfigPropertyInterfaceAdd an optional
validationproperty to the interface:2. Implement Validation Logic in
ValidationServiceAdd a static
validatemethod that iterates throughGlobalConfig.ENTRIESand executes thevalidationfunction if it exists:3. Integrate with
ConfigServiceInvoke
ValidationService.validate(this.envs)in theConfigServiceconstructor afterValidationService.typeCasting(process.env).4. Define Validation for
MIRROR_NODE_MAX_LOGS_PER_TIMESTAMP_SLICE(and potentially other configurations)Impact