@suissa/universal-queues
Version:
Factory universal para mensageria (RabbitMQ, Kafka, SQS) para sistemas distribuídos.
49 lines (45 loc) • 1.85 kB
text/typescript
// src/core/fallback.ts
import { enrichHeaders } from './envelope';
export type FallbackMode = 'DLQ' | 'Outbox' | 'ZoombieQ';
export type FallbackContext = {
headers: Record<string, any>;
route: { exchange?: string; routingKey?: string; topic?: string; subject?: string; queue?: string };
payload: object;
error: unknown;
};
/**
* Decorator agnóstico de mensageria.
* - Enriquece headers (x-event-id, x-event-hash, x-origin)
* - Em erro, chama `this.__runFallback(mode, ctx)` (o driver implementa)
* - Por padrão relança o erro; o driver pode escolher resolver no fallback
*/
export function FallbackMessage(mode: FallbackMode = 'DLQ') {
return function (_target: any, _prop: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = async function (
exchangeOrTopic: string,
routingKeyOrSubject: string,
message: object,
headers: Record<string, any> = {}
) {
const env = enrichHeaders(exchangeOrTopic, routingKeyOrSubject, message, headers);
try {
return await original.apply(this, [exchangeOrTopic, routingKeyOrSubject, message, env.headers]);
} catch (error) {
const run = (this as any).__runFallback as (m: FallbackMode, ctx: FallbackContext) => Promise<any>;
if (typeof run === 'function') {
const ret = await run(mode, {
headers: env.headers,
route: { exchange: exchangeOrTopic, routingKey: routingKeyOrSubject, topic: exchangeOrTopic, subject: routingKeyOrSubject },
payload: message,
error
});
// Se o driver optar por "resolver" no fallback, o retorno sobe
if (ret !== undefined) return ret;
}
throw error;
}
};
return descriptor;
};
}