@reffuse/extension-query 0.1.5 #16
@@ -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: () => <></>,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
<StrictMode>
|
||||
<ReffuseRuntime.Provider>
|
||||
<GlobalContext.Provider layer={layer}>
|
||||
<VQueryErrorHandler />
|
||||
<RouterProvider router={router} />
|
||||
</GlobalContext.Provider>
|
||||
</ReffuseRuntime.Provider>
|
||||
|
||||
@@ -6,6 +6,9 @@ export interface ErrorHandler<E> {
|
||||
readonly handle: <A, SelfE, R>(self: Effect.Effect<A, SelfE, R>) => Effect.Effect<A, Exclude<SelfE, E>, R>
|
||||
}
|
||||
|
||||
export type Error<T> = T extends ErrorHandler<infer E> ? E : never
|
||||
|
||||
|
||||
export const Tag = <const Id extends string>(id: Id) => <
|
||||
Self, E = never,
|
||||
>() => Effect.Tag(id)<Self, ErrorHandler<E>>()
|
||||
|
||||
Reference in New Issue
Block a user