VQueryErrorHandler
All checks were successful
Lint / lint (push) Successful in 12s

This commit is contained in:
Julien Valverdé
2025-03-15 05:12:38 +01:00
parent 0437fa5dcc
commit 4e778b6c95
3 changed files with 62 additions and 12 deletions

View File

@@ -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<Cause.Cause<
ErrorHandler.Error<Context.Tag.Service<QueryErrorHandler>>
>>(), [])
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 => (
<AlertDialog.Root>
<AlertDialog.Content maxWidth="450px">
<AlertDialog.Title>Error</AlertDialog.Title>
<AlertDialog.Description size="2">
{Cause.failures(v).pipe(
Chunk.head,
Option.getOrThrow,
Match.value,
Match.tag("RequestError", () => <Text>HTTP request error</Text>),
Match.tag("ResponseError", () => <Text>HTTP response error</Text>),
Match.exhaustive,
)}
</AlertDialog.Description>
<Flex gap="3" mt="4" justify="end">
<Button variant="solid" color="red" onClick={next}>
Ok
</Button>
</Flex>
</AlertDialog.Content>
</AlertDialog.Root>
),
onNone: () => <></>,
})
}