fix(admin-next, utils, medusa): Handle db errors properly and fix form (#7416)

* fix(admin-next, utils, medusa): Handle db errors properly and fix form

* fix(admin-next, utils, medusa): Handle db errors properly and fix form

* fix(admin-next, utils, medusa): Handle db errors properly and fix form

* fix(admin-next, utils, medusa): Handle db errors properly and fix form
This commit is contained in:
Adrien de Peretti authored and GitHub committed 2024-05-23 12:36:45 +02:00
1 parent e01472aae6
commit 37ae87fe9b
6 files changed
+47 -14

No files matched your search

@@ -0,0 +1,5 @@
import { FetchError } from "@medusajs/js-sdk"
export const isFetchError = (error: any): error is FetchError => {
return error instanceof FetchError
}
@@ -2,6 +2,7 @@ import { zodResolver } from "@hookform/resolvers/zod"
import { ArrowPath, Trash } from "@medusajs/icons" import { ArrowPath, Trash } from "@medusajs/icons"
import { InviteDTO } from "@medusajs/types" import { InviteDTO } from "@medusajs/types"
import { import {
Alert,
Button, Button,
Container, Container,
Heading, Heading,
@@ -29,6 +30,7 @@ import {
} from "../../../../../hooks/api/invites" } from "../../../../../hooks/api/invites"
import { DataTable } from "../../../../../components/table/data-table" import { DataTable } from "../../../../../components/table/data-table"
import { useUserInviteTableQuery } from "../../../../../hooks/table/query/use-user-invite-table-query" import { useUserInviteTableQuery } from "../../../../../hooks/table/query/use-user-invite-table-query"
import { isFetchError } from "../../../../../lib/is-fetch-error.ts"
const InviteUserSchema = zod.object({ const InviteUserSchema = zod.object({
email: zod.string().email(), email: zod.string().email(),
@@ -74,16 +76,18 @@ export const InviteUserForm = () => {
const { mutateAsync, isPending } = useCreateInvite() const { mutateAsync, isPending } = useCreateInvite()
const handleSubmit = form.handleSubmit(async (values) => { const handleSubmit = form.handleSubmit(async (values) => {
await mutateAsync( try {
{ await mutateAsync({ email: values.email })
email: values.email, form.reset()
}, } catch (error) {
{ if (isFetchError(error) && error.status === 400) {
onSuccess: () => { form.setError("root", {
form.reset() type: "manual",
}, message: error.message,
})
return
} }
) }
}) })
if (isError) { if (isError) {
@@ -106,6 +110,17 @@ export const InviteUserForm = () => {
{t("users.inviteUserHint")} {t("users.inviteUserHint")}
</Text> </Text>
</div> </div>
{form.formState.errors.root && (
<Alert
variant="error"
dismissible={false}
className="text-balance"
>
{form.formState.errors.root.message}
</Alert>
)}
<div className="flex flex-col gap-y-4"> <div className="flex flex-col gap-y-4">
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<Form.Field <Form.Field
+9 -3
View File
@@ -45,8 +45,12 @@ const normalizeRequest = (
const normalizeResponse = async (resp: Response, reqHeaders: Headers) => { const normalizeResponse = async (resp: Response, reqHeaders: Headers) => {
if (resp.status >= 300) { if (resp.status >= 300) {
const error = new FetchError(resp.statusText, resp.status) const jsonError = await resp.json().catch(() => ({})) as { message?: string }
throw error throw new FetchError(
jsonError.message ?? resp.statusText,
resp.statusText,
resp.status
)
} }
// If we requested JSON, we try to parse the response. Otherwise, we return the raw response. // If we requested JSON, we try to parse the response. Otherwise, we return the raw response.
@@ -56,9 +60,11 @@ const normalizeResponse = async (resp: Response, reqHeaders: Headers) => {
export class FetchError extends Error { export class FetchError extends Error {
status: number | undefined status: number | undefined
statusText: string | undefined
constructor(message: string, status?: number) { constructor(message: string, statusText?: string, status?: number) {
super(message) super(message)
this.statusText = statusText
this.status = status this.status = status
} }
} }
+1
View File
@@ -21,3 +21,4 @@ class Medusa {
} }
export default Medusa export default Medusa
export { FetchError } from "./client"
@@ -74,7 +74,7 @@ const getConstraintInfo = (err: any) => {
return null return null
} }
const [keys, values] = detail.match(/\([^\(.]*\)/g) || [] const [keys, values] = detail.match(/\([^\(]*\)/g) || []
if (!keys || !values) { if (!keys || !values) {
return null return null
@@ -45,9 +45,15 @@ export const POST = async (
input: { input: {
invites: [req.validatedBody], invites: [req.validatedBody],
}, },
throwOnError: false,
}
const { result, errors } = await workflow.run(input)
if (errors?.length) {
throw errors[0].error
} }
const { result } = await workflow.run(input)
const invite = await refetchInvite( const invite = await refetchInvite(
result[0].id, result[0].id,
req.scope, req.scope,