Upload API give me 502 Bad Gateway
Hi. I'm in a Next js 13 project. I tried to upload a image using an unsigned upload preset call restaurant and Upload API but it gives me a 502 Bad Gateway.
This is my code
'use client' import { useSession } from 'next-auth/react' import { useRouter } from 'next/navigation' import { useState } from 'react' function AddPage() { const { data: session, status } = useSession() const [inputs, setInputs] = useState({ title: '', desc: '', price: 0, catSlug: '' }) const [option, setOption] = useState({ title: '', additionalPrice: 0 }) const [options, setOptions] = useState([]) const [file, setFile] = useState() const router = useRouter() if (status === 'loading') { return <p>Loading...</p> } if (status === 'unauthenticated' || !session?.user.isAdmin) { router.push('/') } const handleChange = (e) => { setInputs((prev) => ({ ...prev, [e.target.name]: e.target.value })) } const changeOption = (e) => { const { name, value } = e.target const newValue = name === 'additionalPrice' ? parseFloat(value) : value setOption((prev) => ({ ...prev, [name]: newValue })) } const handleChangeImage = (e) => { const target = e.target const item = target.files[0] setFile(item) } const upload = async () => { try { const dataForm = new FormData() dataForm.append('file', file) dataForm.append('upload_preset', 'restaurant') dataForm.append('cloud_name', 'stefigallery') const res = await fetch('https://api.cloudinary.com/v1_1/stefigallery/image', { method: 'POST', headers: { 'Content-Type': 'multipart/form-data' }, body: dataForm }) const dataImage = await res.json() return dataImage.url } catch (error) { console.log(error) } } const handleSubmit = async (e) => { e.preventDefault() try { const imageUrl = await upload() const formattedOptions = options.map((opt) => ({ ...opt, additionalPrice: parseFloat(opt.additionalPrice) })) const res = await fetch('http://localhost:3000/api/products', { method: 'POST', body: JSON.stringify({ img: imageUrl, ...inputs, options: formattedOptions }) }) const data = await res.json() // router.push(`/product/${data.id}`) } catch (error) { console.log(error) } } return ( <div className='p-4 my-9 lg:px-20 xl:px-40 h-[calc(100vh-6rem)] md:h-[calc(100vh-9rem)] flex items-center justify-center text-red-500'> <form className='shadow-lg flex flex-wrap gap-4 p-8' onSubmit={handleSubmit}> <h1 className='text-4xl mb-2 text-gray-300 font-bold'>Add New Product</h1> <div className='w-full flex flex-col gap-2'> <label>Title</label> <input type='text' name='title' className='ring-1 ring-red-200 rounded-sm p-2' onChange={handleChange} /> </div> <div className='w-full flex flex-col gap-2'> <label>Image</label> <input type='file' id='file' className='ring-1 ring-red-200 rounded-sm p-2' onChange={handleChangeImage} /> </div> <div className='w-full flex flex-col gap-2'> <label>Description</label> <textarea name='desc' className='ring-1 ring-red-200 rounded-sm' onChange={handleChange}></textarea> </div> <div className='w-full flex flex-col gap-2'> <label>Price</label> <input type='number' name='price' className='ring-1 ring-red-200 rounded-sm p-2' onChange={handleChange} /> </div> <div className='w-full flex flex-col gap-2'> <label>Category</label> <input type='text' name='catSlug' className='ring-1 ring-red-200 rounded-sm p-2' onChange={handleChange} /> </div> <div className='w-full flex flex-col gap-2'> <label>Options</label> <div className='flex gap-3'> <input type='text' placeholder='Title' name='title' className='ring-1 ring-red-200 rounded-sm p-2' onChange={changeOption} /> <input type='number' placeholder='Additional Price' name='additionalPrice' className='ring-1 ring-red-200 rounded-sm p-2' onChange={changeOption} /> </div> <input className='w-52 bg-red-500 text-white p-2 cursor-pointer' type='button' value='Add Option' onClick={() => setOptions((prev) => [...prev, option])} /> </div> <div> {options.map((item) => ( <div className='ring-1 p-2 ring-red-500 rounded-md cursor-pointer' key={item.tile} onClick={() => setOptions(options.filter((option) => option.title !== item.title))}> <span>{item.title}</span> <span>${item.additionalPrice}</span> </div> ))} </div> <button type='submit' className='w-full bg-red-500 text-white p-2'> Add Product </button> </form> </div> ) } export default AddPage
Answers
-
Hi @stefifm,
I am afraid I am not able to locate any 502s in our logs for the cloud
stefigallery
which makes me think that the 502 is actually from your side. I am also not able to see any errors related to uploads so the requests don't even reach Cloudinary.Would you have any error log from your localhost?
Thanks in advance.
Loic
0 -
Hi @Vdeub , I have the same error and here's my code:
"use client";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import { useState } from "react";
type Inputs = {
title: string;
desc: string;
price: number;
catSlug: string;
};
type Option = {
title: string;
additionalPrice: number;
};
const AddPage = () => {
const { data: session, status } = useSession();
const [inputs, setInputs] = useState<Inputs>({
title: "",
desc: "",
price: 0,
catSlug: "",
});
const [option, setOption] = useState<Option>({
title: "",
additionalPrice: 0,
});
const [options, setOptions] = useState<Option[]>([]);
const [file, setFile] = useState<File>();
const router = useRouter();
if (status === "loading") {
return <p>Loading...</p>;
}
if (status === "unauthenticated" || !session?.user.isAdmin) {
router.push("/");
}
const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setInputs((prev) => {
return { ...prev, [e.target.name]: e.target.value };
});
};
const changeOption = (e: React.ChangeEvent<HTMLInputElement>) => {
setOption((prev) => {
return { ...prev, [e.target.name]: e.target.value };
});
};
const handleChangeImg = (e: React.ChangeEvent<HTMLInputElement>) => {
const target = e.target as HTMLInputElement;
const item = (target.files as FileList)[0];
setFile(item);
};
const upload = async () => {
const data = new FormData();
data.append("file", file!);
data.append("upload_preset", "restaurant");
const res = await fetch("https://api.cloudinary.com/v1_1/nayadev/image", {
method: "POST",
headers: { "Content-Type": "multipart/form-data" },
mode: "no-cors",
body: data,
});
const resData = await res.json();
return resData.url;
};
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
const url = await upload();
const res = await fetch("http://localhost:3000/api/products", {
method: "POST",
body: JSON.stringify({
img: url,
...inputs,
options,
}),
});
const data = await res.json();
router.push(`/product/${data.id}`);
} catch (err) {
console.log(err);
}
};
return (
<div>
<form
className="shadow-lg flex flex-wrap gap-4 p-8"
onSubmit={handleSubmit}
>
<h1>Add New Product</h1>
<div className="w-full flex flex-col gap-2">
<label>Image</label>
<input
className="ring-1 ring-red-200 p-2 rounded-sm"
type="file"
onChange={handleChangeImg}
/>
</div>
<div className="w-full flex flex-col gap-2">
<label>Title</label>
<input
onChange={handleChange}
className="ring-1 ring-red-200 p-2 rounded-sm"
type="text"
name="title"
/>
</div>
<div className="w-full flex flex-col gap-2">
<label>Desc</label>
<textarea
onChange={handleChange}
className="ring-1 ring-red-200 p-2 rounded-sm"
name="desc"
/>
</div>
<div className="w-full flex flex-col gap-2">
<label>Price</label>
<input
onChange={handleChange}
className="ring-1 ring-red-200 p-2 rounded-sm"
type="number"
name="price"
/>
</div>
<div className="w-full flex flex-col gap-2">
<label>Category</label>
<input
onChange={handleChange}
className="ring-1 ring-red-200 p-2 rounded-sm"
type="text"
name="catSlug"
/>
</div>
<div className="w-full flex flex-col gap-2">
<label>Options</label>
<div className="w-full flex flex-col gap-2">
<input
onChange={changeOption}
className="ring-1 ring-red-200 p-2 rounded-sm"
type="text"
placeholder="Title"
name="title"
/>
<input
onChange={changeOption}
className="ring-1 ring-red-200 p-2 rounded-sm"
type="number"
placeholder="Additional Price"
name="additionalPrice"
/>
</div>
<div
className="w-52 bg-red-500 text-white p-2"
onClick={() => setOptions((prev) => [...prev, option])}
>
Add Option
</div>
</div>
<div>
{options.map((item) => (
<div
className="ring-1 p-2 ring-red-500 rounded-md cursor-pointer"
key={item.title}
onClick={() =>
setOptions(options.filter((opt) => opt.title !== item.title))
}
>
<span>{item.title}</span>
<span>${item.additionalPrice}</span>
</div>
))}
</div>
<button type="submit" className="p-2 w-full bg-red-500 text-white">
Submit
</button>
</form>
</div>
);
};
export default AddPage;
The console gave this error:
POST https://api.cloudinary.com/v1_1/nayadev/image 502 (Bad Gateway) page.tsx:67
SyntaxError: Unexpected end of input (at page.tsx:75:35)
at upload (page.tsx:75:35)
at async handleSubmit (page.tsx:81:25)
0