0.1.11 #14
@@ -1,57 +0,0 @@
|
|||||||
import { AlertDialog, Button, Flex, Text } from "@radix-ui/themes"
|
|
||||||
import { QueryErrorHandler } from "@reffuse/extension-query"
|
|
||||||
import { Cause, Console, Context, Effect, Either, flow, Match, Option, Stream } from "effect"
|
|
||||||
import { useState } from "react"
|
|
||||||
import { AppQueryErrorHandler } from "./query"
|
|
||||||
import { R } from "./reffuse"
|
|
||||||
|
|
||||||
|
|
||||||
export function VQueryErrorHandler() {
|
|
||||||
const [failure, setFailure] = useState(Option.none<Cause.Cause<
|
|
||||||
QueryErrorHandler.Error<Context.Tag.Service<AppQueryErrorHandler>>
|
|
||||||
>>())
|
|
||||||
|
|
||||||
R.useFork(() => AppQueryErrorHandler.pipe(Effect.flatMap(handler =>
|
|
||||||
Stream.runForEach(handler.errors, v => Console.error(v).pipe(
|
|
||||||
Effect.andThen(Effect.sync(() => { setFailure(Option.some(v)) }))
|
|
||||||
))
|
|
||||||
)), [])
|
|
||||||
|
|
||||||
return Option.match(failure, {
|
|
||||||
onSome: v => (
|
|
||||||
<AlertDialog.Root open>
|
|
||||||
<AlertDialog.Content maxWidth="450px">
|
|
||||||
<AlertDialog.Title>Error</AlertDialog.Title>
|
|
||||||
<AlertDialog.Description size="2">
|
|
||||||
{Either.match(Cause.failureOrCause(v), {
|
|
||||||
onLeft: flow(
|
|
||||||
Match.value,
|
|
||||||
Match.tag("RequestError", () => <Text>HTTP request error</Text>),
|
|
||||||
Match.tag("ResponseError", () => <Text>HTTP response error</Text>),
|
|
||||||
Match.exhaustive,
|
|
||||||
),
|
|
||||||
|
|
||||||
onRight: flow(
|
|
||||||
Cause.dieOption,
|
|
||||||
Option.match({
|
|
||||||
onSome: () => <Text>Unrecoverable defect</Text>,
|
|
||||||
onNone: () => <Text>Unknown error</Text>,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
})}
|
|
||||||
</AlertDialog.Description>
|
|
||||||
|
|
||||||
<Flex gap="3" mt="4" justify="end">
|
|
||||||
<AlertDialog.Action>
|
|
||||||
<Button variant="solid" color="red" onClick={() => setFailure(Option.none())}>
|
|
||||||
Ok
|
|
||||||
</Button>
|
|
||||||
</AlertDialog.Action>
|
|
||||||
</Flex>
|
|
||||||
</AlertDialog.Content>
|
|
||||||
</AlertDialog.Root>
|
|
||||||
),
|
|
||||||
|
|
||||||
onNone: () => <></>,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
57
packages/example/src/VQueryErrorHandler.tsx
Normal file
57
packages/example/src/VQueryErrorHandler.tsx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { AlertDialog, Button, Flex, Text } from "@radix-ui/themes"
|
||||||
|
import { Cause, Console, Effect, Either, flow, Match, Option, Stream } from "effect"
|
||||||
|
import { useState } from "react"
|
||||||
|
import { AppQueryErrorHandler } from "./query"
|
||||||
|
import { R } from "./reffuse"
|
||||||
|
|
||||||
|
|
||||||
|
export function VQueryErrorHandler() {
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
|
||||||
|
const error = R.useSubscribeStream(
|
||||||
|
R.useMemo(() => AppQueryErrorHandler.pipe(
|
||||||
|
Effect.map(handler => handler.errors.pipe(
|
||||||
|
Stream.changes,
|
||||||
|
Stream.tap(Console.error),
|
||||||
|
Stream.tap(() => Effect.sync(() => setOpen(true))),
|
||||||
|
))
|
||||||
|
), [])
|
||||||
|
)
|
||||||
|
|
||||||
|
if (Option.isNone(error))
|
||||||
|
return <></>
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AlertDialog.Root open={open}>
|
||||||
|
<AlertDialog.Content maxWidth="450px">
|
||||||
|
<AlertDialog.Title>Error</AlertDialog.Title>
|
||||||
|
<AlertDialog.Description size="2">
|
||||||
|
{Either.match(Cause.failureOrCause(error.value), {
|
||||||
|
onLeft: flow(
|
||||||
|
Match.value,
|
||||||
|
Match.tag("RequestError", () => <Text>HTTP request error</Text>),
|
||||||
|
Match.tag("ResponseError", () => <Text>HTTP response error</Text>),
|
||||||
|
Match.exhaustive,
|
||||||
|
),
|
||||||
|
|
||||||
|
onRight: flow(
|
||||||
|
Cause.dieOption,
|
||||||
|
Option.match({
|
||||||
|
onSome: () => <Text>Unrecoverable defect</Text>,
|
||||||
|
onNone: () => <Text>Unknown error</Text>,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
})}
|
||||||
|
</AlertDialog.Description>
|
||||||
|
|
||||||
|
<Flex gap="3" mt="4" justify="end">
|
||||||
|
<AlertDialog.Action>
|
||||||
|
<Button variant="solid" color="red" onClick={() => setOpen(false)}>
|
||||||
|
Ok
|
||||||
|
</Button>
|
||||||
|
</AlertDialog.Action>
|
||||||
|
</Flex>
|
||||||
|
</AlertDialog.Content>
|
||||||
|
</AlertDialog.Root>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { VQueryErrorHandler } from "@/QueryErrorHandler"
|
import { VQueryErrorHandler } from "@/VQueryErrorHandler"
|
||||||
import { Container, Flex, Theme } from "@radix-ui/themes"
|
import { Container, Flex, Theme } from "@radix-ui/themes"
|
||||||
import { createRootRoute, Link, Outlet } from "@tanstack/react-router"
|
import { createRootRoute, Link, Outlet } from "@tanstack/react-router"
|
||||||
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"
|
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"
|
||||||
|
|||||||
Reference in New Issue
Block a user