import { SchemaIssue, Schema } from "effect"; import type { ProjectionRepositoryError } from "../persistence/Errors.ts"; export class OrchestrationCommandJsonParseError extends Schema.TaggedErrorClass()( "OrchestrationCommandJsonParseError", { detail: Schema.String, cause: Schema.optional(Schema.Defect), }, ) { override get message(): string { return `Invalid orchestration command JSON: ${this.detail}`; } } export class OrchestrationCommandDecodeError extends Schema.TaggedErrorClass()( "OrchestrationCommandDecodeError", { issue: Schema.String, cause: Schema.optional(Schema.Defect), }, ) { override get message(): string { return `Invalid orchestration command payload: ${this.issue}`; } } export class OrchestrationCommandInvariantError extends Schema.TaggedErrorClass()( "OrchestrationCommandInvariantError", { commandType: Schema.String, detail: Schema.String, cause: Schema.optional(Schema.Defect), }, ) { override get message(): string { return `Orchestration command invariant failed (${this.commandType}): ${this.detail}`; } } export class OrchestrationCommandPreviouslyRejectedError extends Schema.TaggedErrorClass()( "OrchestrationCommandPreviouslyRejectedError", { commandId: Schema.String, detail: Schema.String, cause: Schema.optional(Schema.Defect), }, ) { override get message(): string { return `Command previously rejected (${this.commandId}): ${this.detail}`; } } export class OrchestrationProjectorDecodeError extends Schema.TaggedErrorClass()( "OrchestrationProjectorDecodeError", { eventType: Schema.String, issue: Schema.String, cause: Schema.optional(Schema.Defect), }, ) { override get message(): string { return `Projector decode failed for ${this.eventType}: ${this.issue}`; } } export class OrchestrationListenerCallbackError extends Schema.TaggedErrorClass()( "OrchestrationListenerCallbackError", { listener: Schema.Literals(["read-model", "domain-event"]), detail: Schema.String, cause: Schema.optional(Schema.Defect), }, ) { override get message(): string { return `Orchestration ${this.listener} listener failed: ${this.detail}`; } } export type OrchestrationDispatchError = | ProjectionRepositoryError | OrchestrationCommandInvariantError | OrchestrationCommandPreviouslyRejectedError | OrchestrationProjectorDecodeError | OrchestrationListenerCallbackError; export type OrchestrationEngineError = | OrchestrationDispatchError | OrchestrationCommandJsonParseError | OrchestrationCommandDecodeError; export function toOrchestrationCommandDecodeError(error: Schema.SchemaError) { return new OrchestrationCommandDecodeError({ issue: SchemaIssue.makeFormatterDefault()(error.issue), cause: error, }); } export function toProjectorDecodeError(eventType: string) { return (error: Schema.SchemaError): OrchestrationProjectorDecodeError => new OrchestrationProjectorDecodeError({ eventType, issue: SchemaIssue.makeFormatterDefault()(error.issue), cause: error, }); } export function toOrchestrationJsonParseError(cause: unknown) { return new OrchestrationCommandJsonParseError({ detail: `Failed to parse orchestration command JSON`, cause, }); } export function toListenerCallbackError(listener: "read-model" | "domain-event") { return (cause: unknown): OrchestrationListenerCallbackError => new OrchestrationListenerCallbackError({ listener, detail: `Failed to invoke orchestration ${listener} listener`, cause, }); }