From 4e778b6c95d4b28e4a128b767a08b4997b0b09d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 15 Mar 2025 05:12:38 +0100 Subject: [PATCH] VQueryErrorHandler --- packages/example/src/QueryErrorHandler.tsx | 68 ++++++++++++++++---- packages/example/src/main.tsx | 3 +- packages/extension-query/src/ErrorHandler.ts | 3 + 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/packages/example/src/QueryErrorHandler.tsx b/packages/example/src/QueryErrorHandler.tsx index 003324e..844f7a4 100644 --- a/packages/example/src/QueryErrorHandler.tsx +++ b/packages/example/src/QueryErrorHandler.tsx @@ -1,6 +1,8 @@ import { HttpClientError } from "@effect/platform" +import { AlertDialog, Button, Flex, Text } from "@radix-ui/themes" import { ErrorHandler } from "@reffuse/extension-query" -import { Cause, Chunk, Effect, flow, Match, Stream } from "effect" +import { Cause, Chunk, Context, Effect, Match, Option, Queue, Stream } from "effect" +import { useState } from "react" import { R } from "./reffuse" @@ -12,15 +14,59 @@ export const QueryErrorHandlerLive = ErrorHandler.layer(QueryErrorHandler) export function VQueryErrorHandler() { + const queue = R.useMemo(() => Queue.unbounded> + >>(), []) + R.useFork(() => QueryErrorHandler.pipe(Effect.flatMap(handler => - Stream.runForEach(handler.errors, flow( - Cause.failures, - Chunk.map(flow(Match.value, - Match.tag("RequestError", () => Effect.sync(() => {})), - Match.tag("ResponseError", () => Effect.sync(() => {})), - Match.exhaustive, - )), - Effect.all, - )) - )), []) + Stream.runForEach(handler.errors, v => Queue.offer(queue, v)) + )), [queue]) + + const [failure, setFailure] = useState(R.useMemo(() => Queue.poll(queue), [])) + + const next = R.useCallbackSync(() => Queue.poll(queue).pipe( + Effect.map(setFailure) + ), [queue]) + + // R.useFork(() => QueryErrorHandler.pipe(Effect.flatMap(handler => + // Stream.runForEach(handler.errors, flow( + // Cause.failures, + // Chunk.map(flow(Match.value, + // Match.tag("RequestError", () => Effect.sync(() => {})), + // Match.tag("ResponseError", () => Effect.sync(() => {})), + // Match.exhaustive, + // )), + // Effect.all, + // )) + // )), []) + + + return Option.match(failure, { + onSome: v => ( + + + Error + + {Cause.failures(v).pipe( + Chunk.head, + Option.getOrThrow, + + Match.value, + Match.tag("RequestError", () => HTTP request error), + Match.tag("ResponseError", () => HTTP response error), + Match.exhaustive, + )} + + + + + + + + ), + + onNone: () => <>, + }) } diff --git a/packages/example/src/main.tsx b/packages/example/src/main.tsx index a544300..b058a72 100644 --- a/packages/example/src/main.tsx +++ b/packages/example/src/main.tsx @@ -6,7 +6,7 @@ import { Layer } from "effect" import { StrictMode } from "react" import { createRoot } from "react-dom/client" import { ReffuseRuntime } from "reffuse" -import { QueryErrorHandler, QueryErrorHandlerLive } from "./QueryErrorHandler" +import { QueryErrorHandler, QueryErrorHandlerLive, VQueryErrorHandler } from "./QueryErrorHandler" import { GlobalContext } from "./reffuse" import { routeTree } from "./routeTree.gen" @@ -33,6 +33,7 @@ createRoot(document.getElementById("root")!).render( + diff --git a/packages/extension-query/src/ErrorHandler.ts b/packages/extension-query/src/ErrorHandler.ts index f602f62..7e4e912 100644 --- a/packages/extension-query/src/ErrorHandler.ts +++ b/packages/extension-query/src/ErrorHandler.ts @@ -6,6 +6,9 @@ export interface ErrorHandler { readonly handle: (self: Effect.Effect) => Effect.Effect, R> } +export type Error = T extends ErrorHandler ? E : never + + export const Tag = (id: Id) => < Self, E = never, >() => Effect.Tag(id)>()