_Api endpoint_
Next will log the "API resolved without sending a response" warning even though the API endpoint always send a response back.
Here the code that triggers the warning:
export default async function(req: NextApiRequest, res: NextApiResponse) {
switch (req.method) {
case "POST":
case "OPTION": {
try {
const request = http.request( // Node core http module
url,
{
headers: await makeHeaders(req, res),
method: req.method,
},
response => {
response.pipe(res);
},
);
request.write(JSON.stringify(req.body));
return request.end();
} catch (error) {
Log.error(error); // Can be a simple console.error too
}
return res.status(500).end();
}
}
return res.status(405).end();
}
It seems that this endpoint will always send a response back.
No warning
This has been fixed in canary, can you try next@canary
?
same issue here, i tried next@canary
Next still logs "API resolved without sending a response"
@iddify please provide code instead of saying "same issue", it's unlikely that you're doing 100% exactly the same as the person that posts an issue.
@timneutkens I'm simply trying to Integrate sendgrid to handle a form via this endpoint '/api/bulk-order'
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_APIKEY);
export default function handler(req, res) {
///const { name, email, phone, date, order_desc } = req.body;
const msg = {
to: '[email protected]',
from: '[email protected]',
subject: 'Sending with Twilio SendGrid is Fun',
text: 'and easy to do anywhere, even with Node.js',
html: '<strong>and easy to do anywhere, even with Node.js</strong>'
};
sgMail.send(msg);
}
const sendEmail = (url, emailData) => {
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(emailData)
});
};
const handleSubmitForm = () => {
sendEmail('/api/bulk-order', emailBody);
};
when i submit nothing really happens other the the console logs "API resolved without sending a response for /api/bulk-order, this may result in a stalled requests."
UPDATE: i wasn't resolving the request, returning a 200 status code after the request finished removed the warning for me, MY BAD!
@timneutkens Thank you for the quick reply. Unfortunately 9.2.2-canary.12
doesn't solve the issue 馃槥
I don't know exactly how Next analyzes whether or not a route actually returns something, but it could be because of the callback in http.request
or the try/catch
?
I also wonder if this couldn't be because of the http.request
function that could "silently" fail and just not do anything 馃
I will investigate a bit more 馃憤
@gaku-sei it is most likely caused by the callback
as we can't detect you are still doing work in the API unless you return a promise and wait to resolve it until after the callback is fired e.g.
export default async function(req: NextApiRequest, res: NextApiResponse) {
return new Promise(resolve => {
switch (req.method) {
case "POST":
case "OPTION": {
try {
const request = http.request( // Node core http module
url,
{
headers: await makeHeaders(req, res),
method: req.method,
},
response => {
response.pipe(res);
resolve()
},
);
request.write(JSON.stringify(req.body));
request.end();
} catch (error) {
Log.error(error); // Can be a simple console.error too
res.status(500).end();
return resolve()
}
}
}
res.status(405).end();
return resolve()
})
}
@ijjk Thank you very much, that worked perfectly for me!
Issue solved 馃槃
I see the same warning with apollo-server-express
.
@danielhusar Any idea what could be the valid solution for apollo-server-express? Hitting the same issue "API resolved without sending a response for /, this may result in stalled requests.".
/
is not even called in my app, my endpoint is /api/graphql
.
I havent been able to figure it out yet. Im considering to switch to express server to handle all requests. (Instead of just api)
We're going to add a config option to opt-out of the warning for certain api routes if you're sure they resolve
I'm still running into this:
export default async function token(req, res) {
try {
const { user } = await auth0.getSession(req);
if (user) {
return new Promise((resolve, reject) => {
fetch(`https://${process.env.domain}/oauth/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
grant_type: 'client_credentials',
client_id: process.env.authClientID,
client_secret: process.env.authClientSecret,
audience: `https://${process.env.domain}/api/v2/`,
}),
})
.then((res) => res.json())
.then(({ access_token, scope, expires_in, token_type }) => {
token = { access_token, scope, expires_in, token_type };
console.log(token)
resolve(token);
})
.catch(err => {
reject(err);
})
})
}
else {
throw new Error('No User');
}
} catch (error) {
console.error(error)
res.status(error.status || 500).end(error.message)
}
}
export default async function token(req, res) {
try {
const { user } = await auth0.getSession(req);
if(!user) {
throw new Error('No User');
}
const result = await fetch(`https://${process.env.domain}/oauth/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
grant_type: 'client_credentials',
client_id: process.env.authClientID,
client_secret: process.env.authClientSecret,
audience: `https://${process.env.domain}/api/v2/`,
}),
})
const { access_token, scope, expires_in, token_type } = await result.json()
return { access_token, scope, expires_in, token_type }
} catch (error) {
console.error(error)
return res.status(error.status || 500).end(error.message)
}
}
This should solve your case, but you can now disable the warning also: https://nextjs.org/docs/api-routes/api-middlewares
// export this from the api route
export const config = {
api: {
externalResolver: true,
},
}
I'm not sure I understand. I'm getting it with this code which I got from the example for firebase server authentication:
pages/api/login.ts:
import commonMiddleware from '../../middleware/commonMiddeware';
import { verifyIdToken } from '../../firebase/auth/admin';
const handler = async (req, res) => {
if (!req.body) {
return res.status(400);
}
const { token } = req.body;
try {
const decodedToken = await verifyIdToken(token);
req.session.decodedToken = decodedToken;
req.session.token = token;
return res.status(200).json({ status: true, decodedToken });
} catch (error) {
return res.status(500).json({ error });
}
};
export default commonMiddleware(handler);
Looks like you're not finishing the request when a body is not set:
if (!req.body) {
return res.status(400);
}
Should be:
if (!req.body) {
return res.status(400).send({});
}
Looks like you're not finishing the request when a body is not set:
if (!req.body) { return res.status(400); }
Should be:
if (!req.body) { return res.status(400).send({}); }
Have the same problem and the above fix isn't working for me. :/
I have the same problem. The message just a warning or can it really give you problems?
I'm having the same problem. Why is this issue closed? Is this a problem from Next server or am I doing something wrong?
+1 same for me
I am getting this same warning too however I am getting the data I expect to revieve in the console :/
Updated to next@canary
and I'm still seeing this error.
here's my handler:
const trades = mongoMiddleware(async (req, res, connection, models) => {
const {
method
} = req
apiHandler(res, method, {
GET: (response) => {
models.Trade.find({}, (error, trade) => {
if (error) {
connection.close();
response.status(500).json({ error });
} else {
response.status(200).json(trade);
connection.close();
}
})
}
});
})
When I hit my route I get a json array returned with all the trades.. but I get this in the console:
API resolved without sending a response for /api/trades, this may result in stalled requests.
People still running into this issue might want to look closely at: https://github.com/vercel/next.js/issues/10439#issuecomment-633013628 and https://github.com/vercel/next.js/pull/11380
If you're using an externalResolver (such as Express), nextjs can't detect that the API response has been send. At the bottom of https://github.com/vercel/next.js/issues/10439#issuecomment-633013628 @timneutkens explains how you can disable the warning if that is indeed the case.
Most helpful comment
@gaku-sei it is most likely caused by the
callback
as we can't detect you are still doing work in the API unless you return a promise and wait to resolve it until after the callback is fired e.g.