Esteves Enzo commited on
Commit
0891679
·
1 Parent(s): 25c0ab6

manage error

Browse files
app/api/route.ts CHANGED
@@ -6,13 +6,11 @@ const prisma = new PrismaClient()
6
  export async function POST(
7
  request: Request,
8
  ) {
9
- const { inputs } = await request.json()
10
-
11
  const response = await fetch('https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0', {
12
  method: 'POST',
13
  body: JSON.stringify({
14
  inputs,
15
- stream: true,
16
  }),
17
  headers: {
18
  Authorization: `Bearer ${process.env.NEXT_PUBLIC_APP_HF_TOKEN}`,
@@ -21,6 +19,10 @@ export async function POST(
21
  },
22
  })
23
 
 
 
 
 
24
  const blob = await response.blob()
25
  const headers = new Headers();
26
  headers.set("Content-Type", "image/*");
@@ -35,5 +37,6 @@ export async function POST(
35
  },
36
  })
37
 
38
- return Response.json({ blob: new_blob, status: 200, statusText: "OK", headers });
 
39
  }
 
6
  export async function POST(
7
  request: Request,
8
  ) {
9
+ const { inputs } = await request.json()
 
10
  const response = await fetch('https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0', {
11
  method: 'POST',
12
  body: JSON.stringify({
13
  inputs,
 
14
  }),
15
  headers: {
16
  Authorization: `Bearer ${process.env.NEXT_PUBLIC_APP_HF_TOKEN}`,
 
19
  },
20
  })
21
 
22
+ // avoid json parse error
23
+ const res = await response.clone().json().catch(() => ({}));
24
+ if (res?.error) return Response.json({ status: response.status, ok: false, message: res.error });
25
+
26
  const blob = await response.blob()
27
  const headers = new Headers();
28
  headers.set("Content-Type", "image/*");
 
37
  },
38
  })
39
 
40
+ return Response.json({ blob: new_blob, status: 200, ok: true, headers });
41
+
42
  }
components/main/collections/collection.tsx CHANGED
@@ -9,7 +9,7 @@ interface Props {
9
  index: number;
10
  collection: CollectionType;
11
  className?: string;
12
- onOpen: (id: number) => void;
13
  }
14
 
15
  export const Collection: React.FC<Props> = ({
 
9
  index: number;
10
  collection: CollectionType;
11
  className?: string;
12
+ onOpen: (id: string) => void;
13
  }
14
 
15
  export const Collection: React.FC<Props> = ({
components/main/collections/index.tsx CHANGED
@@ -23,8 +23,24 @@ export const Collections: React.FC<{ category: string }> = ({ category }) => {
23
  <>
24
  <div className="mx-auto grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-5 mt-8 lg:mt-14">
25
  {collections?.map((collection: CollectionType, i: number) =>
26
- collection?.id === -1 ? (
27
- <CollectionLoading key={i} prompt={collection.prompt} />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  ) : (
29
  <Collection
30
  key={category + collection.id}
 
23
  <>
24
  <div className="mx-auto grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-5 mt-8 lg:mt-14">
25
  {collections?.map((collection: CollectionType, i: number) =>
26
+ collection?.loading ? (
27
+ <CollectionLoading
28
+ key={i}
29
+ prompt={collection.prompt}
30
+ error={collection.error}
31
+ className={classNames("", {
32
+ "!translate-y-12":
33
+ breakpoint === "XL"
34
+ ? i % 5 === 1 || i % 5 === 3
35
+ : breakpoint === "L"
36
+ ? i % 4 === 1 || i % 4 === 3
37
+ : breakpoint === "S"
38
+ ? i % 3 === 1
39
+ : breakpoint === "XS"
40
+ ? i % 2 === 1
41
+ : false,
42
+ })}
43
+ />
44
  ) : (
45
  <Collection
46
  key={category + collection.id}
components/main/collections/loading.tsx CHANGED
@@ -1,27 +1,42 @@
1
- import { useMemo } from "react";
2
  import { motion } from "framer-motion";
3
-
4
- import { Collection as CollectionType } from "@/utils/type";
5
 
6
  interface Props {
7
  prompt: string;
 
 
8
  }
9
 
10
- export const CollectionLoading: React.FC<Props> = ({ prompt }) => {
 
 
 
 
11
  return (
12
- <div className="h-[377px] w-full relative">
13
  <motion.div
14
  initial={{ y: 100, opacity: 0 }}
15
  animate={{ y: 0, opacity: 1 }}
16
  transition={{ duration: 0.35, delay: 0.1 }}
17
- className="rounded-3xl h-[377px] cursor-pointer group overflow-hidden relative z-[1] group bg-primary/70 flex flex-col justify-between p-8"
 
 
 
 
 
 
18
  >
19
- <div className="loading-dots translate-y-[5px]">
20
- <span />
21
- <span />
22
- <span />
23
- </div>
24
- <p className="text-white/50 font-semibold text-xl">{prompt}</p>
 
 
 
 
25
  </motion.div>
26
  </div>
27
  );
 
 
1
  import { motion } from "framer-motion";
2
+ import { FaSadCry } from "react-icons/fa";
3
+ import classNames from "classnames";
4
 
5
  interface Props {
6
  prompt: string;
7
+ error?: string;
8
+ className?: string;
9
  }
10
 
11
+ export const CollectionLoading: React.FC<Props> = ({
12
+ prompt,
13
+ error,
14
+ className,
15
+ }) => {
16
  return (
17
+ <div className={`h-[377px] w-full relative ${className}`}>
18
  <motion.div
19
  initial={{ y: 100, opacity: 0 }}
20
  animate={{ y: 0, opacity: 1 }}
21
  transition={{ duration: 0.35, delay: 0.1 }}
22
+ className={classNames(
23
+ "rounded-3xl h-[377px] cursor-pointer group relative group flex flex-col justify-between p-8 z-[1]",
24
+ {
25
+ "bg-primary/70": !error,
26
+ "bg-red-500/80 ring-8 ring-red-400/20": error,
27
+ }
28
+ )}
29
  >
30
+ {error ? (
31
+ <FaSadCry className="text-white/60 text-5xl" />
32
+ ) : (
33
+ <div className="loading-dots translate-y-[5px]">
34
+ <span />
35
+ <span />
36
+ <span />
37
+ </div>
38
+ )}
39
+ <p className="text-white/70 font-semibold text-xl">{error ?? prompt}</p>
40
  </motion.div>
41
  </div>
42
  );
components/main/hooks/useInputGeneration.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { useState } from "react"
2
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
3
  import { useLocalStorage } from 'react-use';
4
 
@@ -26,10 +26,13 @@ export const useInputGeneration = () => {
26
  const { mutate: submit, isLoading: loading } = useMutation(
27
  ["generation"],
28
  async () => {
 
 
29
  if (!hasMadeFirstGeneration) setFirstGenerationDone()
30
  client.setQueryData(["collections"], (old) => {
31
  return [{
32
- id: -1,
 
33
  blob: {
34
  type: "image/png",
35
  data: new ArrayBuffer(0),
@@ -49,23 +52,26 @@ export const useInputGeneration = () => {
49
  })
50
  const data = await response.json()
51
 
52
- if (!response.ok) {
53
- throw new Error(data.message)
54
- }
55
-
56
  client.setQueryData(["collections"], (old) => {
57
  const newArray = [...old as Collection[]]
58
- const index = newArray.findIndex((item: Collection) => item.id === -1)
 
 
59
 
60
- newArray[index] = data?.blob as Collection
 
 
 
61
 
62
  return newArray
63
  })
64
 
 
 
65
  setGenerationsId(myGenerationsId?.length ? [...myGenerationsId, data?.blob?.id] : [data?.blob?.id])
66
  setOpen(data?.blob?.id)
67
  return data ?? {}
68
- },
69
  )
70
 
71
  const { data: hasMadeFirstGeneration } = useQuery(["firstGenerationDone"], () => {
 
1
+ import { useId, useState } from "react"
2
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
3
  import { useLocalStorage } from 'react-use';
4
 
 
26
  const { mutate: submit, isLoading: loading } = useMutation(
27
  ["generation"],
28
  async () => {
29
+ // generate string random ID
30
+ const id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
31
  if (!hasMadeFirstGeneration) setFirstGenerationDone()
32
  client.setQueryData(["collections"], (old) => {
33
  return [{
34
+ id,
35
+ loading: true,
36
  blob: {
37
  type: "image/png",
38
  data: new ArrayBuffer(0),
 
52
  })
53
  const data = await response.json()
54
 
 
 
 
 
55
  client.setQueryData(["collections"], (old) => {
56
  const newArray = [...old as Collection[]]
57
+ const index = newArray.findIndex((item: Collection) => item.id === id)
58
+
59
+ console.log(data, index, newArray[index])
60
 
61
+ newArray[index] = !data.ok ? {
62
+ ...newArray[index],
63
+ error: data.message
64
+ } : data?.blob as Collection
65
 
66
  return newArray
67
  })
68
 
69
+ if (!data.ok) return null
70
+
71
  setGenerationsId(myGenerationsId?.length ? [...myGenerationsId, data?.blob?.id] : [data?.blob?.id])
72
  setOpen(data?.blob?.id)
73
  return data ?? {}
74
+ }
75
  )
76
 
77
  const { data: hasMadeFirstGeneration } = useQuery(["firstGenerationDone"], () => {
components/modal/useCollection.ts CHANGED
@@ -3,7 +3,7 @@ import { useQuery, useQueryClient } from "@tanstack/react-query"
3
 
4
  import { Collection } from "@/utils/type"
5
 
6
- export const useCollection = (id?: number) => {
7
  const { data: open } = useQuery(["modal"], () => {
8
  return null
9
  }, {
@@ -12,7 +12,7 @@ export const useCollection = (id?: number) => {
12
  refetchOnReconnect: false,
13
  initialData: null
14
  })
15
- const setOpen = (id: number | null) => client.setQueryData(["modal"], () => id)
16
 
17
  const client = useQueryClient()
18
 
 
3
 
4
  import { Collection } from "@/utils/type"
5
 
6
+ export const useCollection = (id?: string) => {
7
  const { data: open } = useQuery(["modal"], () => {
8
  return null
9
  }, {
 
12
  refetchOnReconnect: false,
13
  initialData: null
14
  })
15
+ const setOpen = (id: string | null) => client.setQueryData(["modal"], () => id)
16
 
17
  const client = useQueryClient()
18
 
utils/type.ts CHANGED
@@ -1,9 +1,11 @@
1
  export interface Collection {
2
- id: number;
3
  blob: {
4
  type: string;
5
  data: ArrayBuffer
6
  };
7
  prompt: string;
8
  createdAt: string;
 
 
9
  }
 
1
  export interface Collection {
2
+ id: string;
3
  blob: {
4
  type: string;
5
  data: ArrayBuffer
6
  };
7
  prompt: string;
8
  createdAt: string;
9
+ error?: string;
10
+ loading?: boolean;
11
  }