@@ -166,6 +166,8 @@ export interface ProcessOutboxResult {
166166 deadLettered : number
167167 leaseLost : number
168168 reaped : number
169+ /** Ready event types left pending because their handler module failed to import. */
170+ unloadedEventTypes : string [ ]
169171}
170172
171173export type ProcessSingleOutboxResult =
@@ -457,7 +459,7 @@ export async function processOutboxEvents(
457459 reaped = await reapStuckProcessingRows ( )
458460 phase = 'discover'
459461 const readyTypes = await db . execute < { eventType : string } > ( readyEventTypesQuery ( new Date ( ) ) )
460- const { handlers, eligibleTypes } = await resolveOutboxHandlers (
462+ const { handlers, eligibleTypes, unloadedEventTypes } = await resolveOutboxHandlers (
461463 handlerGroups ,
462464 readyTypes . map ( ( { eventType } ) => eventType )
463465 )
@@ -497,7 +499,7 @@ export async function processOutboxEvents(
497499 else retried ++
498500 }
499501
500- return { processed, retried, deadLettered, leaseLost, reaped }
502+ return { processed, retried, deadLettered, leaseLost, reaped, unloadedEventTypes }
501503 } catch ( error ) {
502504 logger . error ( 'Outbox processing failed' , {
503505 phase,
@@ -517,13 +519,17 @@ export async function processOutboxEvents(
517519 * Imports the groups that serve any ready event type and returns the types to claim this run. A
518520 * group whose import fails leaves its event types unclaimed: unlike a missing handler, which
519521 * spends an attempt and eventually dead-letters, a failed import says nothing about the events,
520- * so they stay pending for a later run. Event types outside every group stay eligible and reach
521- * the missing-handler path.
522+ * so they stay pending for a later run and are reported as `unloadedEventTypes`. Event types
523+ * outside every group stay eligible and reach the missing-handler path.
522524 */
523525async function resolveOutboxHandlers (
524526 groups : readonly LazyOutboxHandlerGroup [ ] ,
525527 readyEventTypes : string [ ]
526- ) : Promise < { handlers : OutboxHandlerRegistry ; eligibleTypes : string [ ] } > {
528+ ) : Promise < {
529+ handlers : OutboxHandlerRegistry
530+ eligibleTypes : string [ ]
531+ unloadedEventTypes : string [ ]
532+ } > {
527533 const unavailableEventTypes = new Set < string > ( )
528534 const ready = new Set ( readyEventTypes )
529535 const dueGroups = groups . filter ( ( group ) => group . events . some ( ( eventType ) => ready . has ( eventType ) ) )
@@ -547,6 +553,7 @@ async function resolveOutboxHandlers(
547553 return {
548554 handlers,
549555 eligibleTypes : readyEventTypes . filter ( ( eventType ) => ! unavailableEventTypes . has ( eventType ) ) ,
556+ unloadedEventTypes : readyEventTypes . filter ( ( eventType ) => unavailableEventTypes . has ( eventType ) ) ,
550557 }
551558}
552559
0 commit comments