Validation
Source:
packages/core/src/core/monitoring/validation.ts,packages/core/src/core/monitoring/event-validation.ts,packages/core/src/core/errors.ts
validateConfig
function validateConfig(config: Journey, allJourneys?: Journey[]): void;Validates a journey configuration. Performs Zod schema validation first, then structural checks for bounce chances, time spans, suppression periods, and duplicate IDs. When allJourneys is provided, also validates cross-journey references and detects circular dependencies.
Throws ZodError for schema failures or SynodeError for structural issues.
import { validateConfig } from '@synode/core';
// Single journey
validateConfig(journey);
// Cross-journey validation
validateConfig(purchaseJourney, [browseJourney, purchaseJourney]);dryRun
async function dryRun(journey: Journey, userCount?: number): Promise<Event[]>;Validates the journey, then generates events for userCount users (default: 1) and returns them in memory. Useful for quick smoke tests without configuring an adapter.
import { dryRun } from '@synode/core';
const events = await dryRun(journey, 3);
console.log(`Generated ${events.length} events for 3 users`);SynodeError
Structured error class for all Synode validation and runtime errors. Extends Error.
class SynodeError extends Error {
readonly code: ErrorCode;
readonly path: string[];
readonly suggestion: string | undefined;
readonly rawMessage: string;
readonly expected: string | undefined;
readonly received: string | undefined;
constructor(options: SynodeErrorOptions);
format(): string;
}format()
Returns a structured multi-line representation:
[INVALID_BOUNCE_CHANCE] Bounce chance must be between 0 and 1
Path: Journey 'Purchase Flow' > Adventure 'Checkout'
Expected: 0 <= bounceChance <= 1
Received: 1.5
Fix: Use a decimal like 0.3, not 30SynodeErrorOptions
interface SynodeErrorOptions {
code: ErrorCode;
message: string;
path: string[];
suggestion?: string;
expected?: string;
received?: string;
cause?: unknown;
}ErrorCode
Union type of all 13 error codes:
| Code | Thrown when |
|---|---|
INVALID_BOUNCE_CHANCE | Bounce chance is outside 0-1 range |
INVALID_TIME_SPAN | TimeSpan min exceeds max |
INVALID_SUPPRESSION_PERIOD | Suppression period min exceeds max |
UNKNOWN_JOURNEY_REF | requires references a non-existent journey |
CIRCULAR_DEPENDENCY | Journey prerequisites form a cycle |
DUPLICATE_ID | Same ID used twice in adventures or actions |
DATASET_NOT_FOUND | ctx.dataset() called with unregistered ID |
DATASET_EMPTY | Dataset has zero rows when a row is requested |
HANDLER_ERROR | Unhandled exception inside an action handler |
ADAPTER_WRITE_ERROR | OutputAdapter.write() threw during output |
INVALID_HANDLER_RETURN | Action handler returned non-array value |
TYPO_DETECTED | Fuzzy match found a likely typo in an identifier |
INVALID_DATASET_COUNT | Dataset count is negative, non-finite, or > 10M |
SynodeValidationError
Error thrown when an event fails schema validation in strict mode. Extends Error.
class SynodeValidationError extends Error {
readonly event: Event;
readonly issues: ValidationIssue[];
constructor(options: SynodeValidationErrorOptions);
}
interface ValidationIssue {
path: (string | number)[];
message: string;
code: string;
}ValidationSummary
Aggregate summary of event validation results, accumulated during generation.
interface ValidationSummary {
eventsValidated: number;
eventsValid: number;
eventsInvalid: number;
validationErrors: { eventName: string; path: string; message: string }[];
}Errors are capped at 50 entries. Created internally by createValidationSummary().
defineEventSchema
function defineEventSchema<T extends z.ZodRawShape>(shape: T): z.ZodObject<T>;Convenience wrapper around z.object() for defining event payload schemas.
import { z } from 'zod';
import { defineEventSchema } from '@synode/core';
const addToCartSchema = defineEventSchema({
productId: z.string(),
quantity: z.number().int().positive(),
price: z.number().positive(),
});