error TypeError: Cannot read properties of undefined (reading 'headers')
Answered
Standard Chinchilla posted this in #help-forum
Standard ChinchillaOP
Keeps on returning this when hitting this endpoint
import { prisma } from '../../../lib/prisma'
export async function POST(request: Request) {
const res: = await request.json()
const userExists = await prisma.user.findUnique({
where: {
email: res.email,
},
})
}
77 Replies
are you sure this code is correct? it says
res: = await request.json()
Standard ChinchillaOP
yea I mean i put the type now
import { hash } from 'bcrypt'
import { prisma } from '../../../lib/prisma'
import { CreateUserDto } from '../../../types'
export async function POST(request: Request) {
const res: CreateUserDto = await request.json()
const userExists = await prisma.user.findUnique({
where: {
email: res.email,
},
})
if (!userExists) {
const hashedPassword = await hash(res.password, 10)
const user = await prisma.user.create({
data: { email: res.email, name: res.name, password: hashedPassword },
})
delete user.password
return user
}
}
and what is the error
Standard ChinchillaOP
error TypeError: Cannot read properties of undefined (reading 'headers')
i dont think ure supposed to return
user
you need to return
so if you're returning json object its
or if its just a status its
NextResponse
so if you're returning json object its
return NextResponse.json(...data...)
or if its just a status its
return new NextResponse(undefined, {status: 200})
Standard ChinchillaOP
I mean not like that yes
in what line did this error occur?
Standard ChinchillaOP
dk
its giving webpack stuff
try sending the whole error log
Standard ChinchillaOP
thats it
thats it
happens as soon as I hit the endpoint
export async function POST(request: Request) {
const res: CreateUserDto = await request.json()
const userExists = await prisma.user.findUnique({
where: {
email: res.email,
},
})
if (!userExists) {
const hashedPassword = await hash(res.password, 10)
const user = await prisma.user.create({
data: { email: res.email, name: res.name, password: hashedPassword },
})
//@ts-ignore
delete user.password
return NextResponse.json(user)
} else {
console.log(userExists)
//@ts-ignore
delete userExists.password
NextResponse.json(userExists)
}
}
sometimes it sends sometimes it doesn't
this smells like a nextjs bug icl
does a very minimal endpoint work?
export async function POST(request: Request) {
const json = await request.json();
console.log(json);
return NextResponse.json({});
}
Standard ChinchillaOP
export async function GET() {
console.log('GET /api/whop')
}
this doesn't
import { NextResponse } from 'next/server'
export async function POST(request: Request) {
const json = await request.json()
console.log(json)
return NextResponse.json({})
}
this des
wdym by doesn't and does?
both of these should work by the way
Standard ChinchillaOP
returns the header error
hmm interesting, this is 99% a nextjs bug now
Standard ChinchillaOP
seems to be
100% a nextjs bug, i can reproduce
except... it's not? this throws the error
but this doesn't
export async function POST(request: Request) {
const json = await request.json();
console.log(json);
}
but this doesn't
import { NextResponse } from "next/server";
export async function POST(request: Request) {
const json = await request.json();
console.log(json);
return NextResponse.json({});
}
Standard ChinchillaOP
yes ig when you don't return
NextResponse
it happens
should still be a bug, at least the error should've been clearer
Standard ChinchillaOP
yes
i reported it here https://github.com/vercel/next.js/issues/51130
Answer
Standard ChinchillaOP
@joulev
import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { prisma } from '../../../lib/prisma'
import { authOptions } from '../../authOptions'
import { redirect } from 'next/navigation'
export const dynamic = 'force-dynamic'
export async function GET(request: NextRequest, response: NextResponse) {
const session = await getServerSession(authOptions)
const url = new URL(request.url)
const params = new URLSearchParams(url.search)
const code = params.get('code')
if (!session) {
return NextResponse.json('No user in session', { status: 400 })
}
if (!code) {
return NextResponse.json('Invalid Request')
}
try {
const res = await (
await fetch('https://data.whop.com/api/v3/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: code,
client_id: process.env.WHOP_CLIENT_ID,
client_secret: process.env.WHOP_CLIENT_SECRET,
redirect_uri: process.env.WHOP_REDIRECT_URI,
}).toString(),
})
).json()
console.log(res.access_token)
const userDetails = await (
await fetch('https://api.whop.com/api/v2/me', {
headers: {
Authorization: `Bearer ${res.access_token}`,
},
})
).json()
console.log(userDetails)
await prisma.user.update({
where: {
email: session?.user.email!,
},
data: {
whopId: userDetails.id,
},
})
return redirect('/')
} catch (e) {
NextResponse.json({ errors: `${e}` }, { status: 400 })
}
}
I have this now I am supposed to redirect how do i do that
it keeps on throwing that error
try removing the return before redirect()
redirect() throws an error so doesnt need return
oh wait
redirect() throws an error, so your try-catch is catching it
you should not catch it
Standard ChinchillaOP
didnt work
yes
hmm
rewrite this to something like
try {
// do other things
} catch (e) {
return NextResponse.json({ errors: `${e}` }, { status: 400 })
}
// move redirect outside the try-catch
redirect('/')
if an error is caught, it will return that json
so
redirect()
is only run in the happy pathStandard ChinchillaOP
kk
works thanks
i will now close this thread, if you have a new question feel free to make a new one
Standard ChinchillaOP
Okay no issues
King Rail
Did you find a fix for the headers bug? I am experiencing the same thing.
You have to return a response
Either return a Response or return a NextResponse
King Rail
I do that
But for some reason still get the error
well you need to show some code
with this much info i obviously cannot say anything
King Rail
Of course not, was just wondering if you had heard something.
This is my code to return a response:
allProducts is a array of stripe products.
I have tried playing around with different headers, removing them and so on.
This is my code to return a response:
return NextResponse.json(
{ products: allProducts },
{
status: 200,
headers: {
"content-type": "application/json",
},
}
)
allProducts is a array of stripe products.
I have tried playing around with different headers, removing them and so on.
you must have a branch of code (e.g. an if/else, a try/catch) where the function terminates without a response
you can add the return type e.g.
export function GET(): Response
to ensure ts tells you where you forget to return the said responseKing Rail
Maybe, i am moving the api from an express js api to a nextjs api route. Everything is tested and works in the expressjs api, just need to change out the parts for the nextjs api.
How do you fetch the api?
How do you fetch the api?
the fetch isn't important, you fetch it like any other apis
King Rail
Okay
Well i am going to take a look at the route. Thank you!
You were right, i had a poorly writting try catch block. I am not sure why it worked fine in express tho. Thank you again!
express most likely returns a default 200? response implicitly in that case
i would love nextjs to do that as well, but at the moment nextjs penalises all unreturned functions with this weird error so what to do
King Rail
If the error was better explained it is probably fine that they do it this way. Makes people check their code through again i guess.
yeah. i'm personally fine with both ways, but they absolutely need to get a better error message here at least