Skip to content

Enhance ConfigService with Custom Validation Support #4840

Description

@quiet-node

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions