diff --git a/packages/extension-query/src/ErrorHandler.ts b/packages/extension-query/src/ErrorHandler.ts index c3cf4aa..b777526 100644 --- a/packages/extension-query/src/ErrorHandler.ts +++ b/packages/extension-query/src/ErrorHandler.ts @@ -1,10 +1,10 @@ -import { type Cause, Context, Effect, Layer, Queue, Stream } from "effect" +import { Cause, Context, Effect, identity, Layer, Queue, Stream } from "effect" import type { Mutable } from "effect/Types" export interface ErrorHandler { readonly errors: Stream.Stream> - readonly handle: (self: Effect.Effect) => Effect.Effect, R> + readonly handle: (self: Effect.Effect) => Effect.Effect, R> } export type Error = T extends ErrorHandler ? E : never @@ -14,24 +14,41 @@ export interface ServiceResult extends Context.TagCl readonly Live: Layer.Layer } -export const Service = (id: Id) => ( - (): ServiceResult => { +export const Service = () => ( + ( + id: Id, + f: ( + self: Effect.Effect, + failure: (failure: E) => Effect.Effect, + defect: (defect: unknown) => Effect.Effect, + ) => Effect.Effect, + ): ServiceResult => { const TagClass = Context.Tag(id)() as ServiceResult + (TagClass as Mutable).Live = Layer.effect(TagClass, Effect.gen(function*() { const queue = yield* Queue.unbounded>() const errors = Stream.fromQueue(queue) - const handle = ( + const handle = ( self: Effect.Effect - ) => Effect.tapErrorCause(self, cause => - Queue.offer(queue, cause as Cause.Cause) - ) as Effect.Effect, R> + ): Effect.Effect, R> => f(self, + (failure: E) => Queue.offer(queue, Cause.fail(failure)).pipe( + Effect.andThen(Effect.failCause(Cause.empty)) + ), + (defect: unknown) => Queue.offer(queue, Cause.die(defect)).pipe( + Effect.andThen(Effect.failCause(Cause.empty)) + ), + ) return { errors, handle } })) + return TagClass } ) -export class DefaultErrorHandler extends Service("@reffuse/extension-query/DefaultErrorHandler")() {} +export class DefaultErrorHandler extends Service()( + "@reffuse/extension-query/DefaultErrorHandler", + identity, +) {}