export const getServerSideProps = async () => {
const res = await axios.get('http://localhost:3000/api/products');
return {
props: {
kebabList: res.data
}
}
};
// get all the products
if (method === "GET") {
try {
const products = await Product.find();
res.status(200).json(products);
} catch (err) {
res.status(500).json(err);
}
}
When I first load the app it is showing this error
Server Error
Error: Request failed with status code 500
If I reload again then it works fine but after deploying on vercel the error is permanent
When you have deployed your app on vercel, your API url might be changed http://localhost:3000 to http://your-domain(live-url).com.
export const getServerSideProps = async () => {
const res = await axios.get('http://your-domain(live-url).com/api/products'); // please focus on this line. I belive you have messed up here
return {
props: {
kebabList: res.data
}
}
};
// get all the products
if (method === "GET") {
try {
const products = await Product.find();
res.status(200).json(products);
} catch (err) {
res.status(500).json(err);
}
}
Related
So I deployed a project on vercel and every page that uses getServerSideProps shows a gateway timeout error.
The most annoying thing is there's nothing in the console. I tried to find the error by adding logs inside the getServerSideProps function but the timeout happens before it even gets inside getServerSideProps.
I erased everything from my getServerSideProps function and only returned a static string and even then it shows timeout.
Here's my latest getServeraSideProps code :
export const getServerSideProps = async () => {
try {
// const res = await fetch(
// `${process.env.NEXT_PUBLIC_API}/api/v1/user/vendors?page=1&limit=12&sortField=createdAt&sortValue=-1`,
// {
// method: "GET",
// headers: {
// "Content-Type": "application/json",
// },
// }
// );
// const data = await res.json();
// return {
// props: {
// vendors: data.data.vendors,
// count: data.data.count,
// },
// };
return {
props: {
data: "Just a string",
},
};
} catch (reason) {
console.log("API:", process.env.NEXT_PUBLIC_API);
// console.log("vendorId:", context.params.vendorId);
// just log it out to stdout
if (reason instanceof Error) {
console.log(reason.message);
} else {
console.log("Unexpected exception", reason);
}
return {
props: {
vendors: [],
count: 0,
},
};
}
As you can see I commented the part where i call the api and I am directly returning a string in the props.
Here's an image of my Vercel Log :
I am using NextJS and created three layers that separate the logic.
The purpose is to minimise the error handling to the getServerSideProps section. I want to get all the lists from the database.
In the first layer, in the API route I created a folder called get-all-lists and a file [userId].js. The get request will be 'http://localhost:3000/api/get-all-lists/iudga937gr8'. Bellow there is the api route that get all the lists with the help of Prsima. It is working perfectly
import prisma from '../../../lib/prisma'
export default async function handler(req, res) {
const { userId } = req.query;
if (req.method === 'GET') {
try {
const shoppingLists = await prisma.List.findMany({ where: { userId: userId }});
res.status(200).json({lists: shoppingLists});
}
catch (error) {
console.log(error);
res.status(500).json({ message: 'Something went wrong. Please try again'});
}
}
else {
res.status(500).json({message: 'Invalid method requested!'});
}
}
The next layer, is the abstraction one which sent the final result to getServerSideProps. I created this because I need to fetch alot of requests and it would be too messy...
export const getAllLists = async userId => {
try {
const lists = await axios.get(`/api/get-all-lists/${userId}`);
return lists;
}
catch (error) {
console.log('Abstraction layer error: ', error);
return 'Something went wrong. Please try again later';
}
}
The problem arise here. In the postman I have the right result. In postman I use http://localhost:3000/api/get-all-lists/clbcpc0hi0002sb1wsiea3q5d and the server sent me the array specified.
But this function does not work and send me this error:
Abstraction layer error: TypeError [ERR_INVALID_URL]: Invalid URL
at new NodeError (node:internal/errors:371:5)
at onParseError (node:internal/url:552:9)
at new URL (node:internal/url:628:5)
at dispatchHttpRequest (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/adapters/http.js:176:20)
at new Promise (<anonymous>)
at http (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/adapters/http.js:112:10)
at Axios.dispatchRequest (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/core/dispatchRequest.js:51:10)
at Axios.request (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/core/Axios.js:142:33)
at Axios.<computed> [as get] (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/core/Axios.js:168:17)
at Function.wrap [as get] (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/helpers/bind.js:5:15) {
input: '/api/get-all-lists/clbcpc0hi0002sb1wsiea3q5d',
code: 'ERR_INVALID_URL'
}
I also tried to paste the localhost in the browser and it have no problem.
You could extract the functionality into /lib/getAllList.js:
import prisma from './prisma';
export default async function getAllLists(userId) {
return await prisma.List.findMany({ where: { userId: userId }});
}
Then use it in your API route:
import getAllLists from '../../../lib/getAllLists';
export default async function handler(req, res) {
const { userId } = req.query;
if (req.method === 'GET') {
try {
const shoppingLists = await getAllLists(userId);
res.status(200).json({lists: shoppingLists});
}
catch (error) {
console.log(error);
res.status(500).json({ message: 'Something went wrong. Please try again'});
}
}
else {
res.status(500).json({message: 'Invalid method requested!'});
}
}
Then use it in getServerSideProps:
import getAllLists from 'path/to/lib/getAllLists';
export async function getServerSideProps(context) {
const { userId } = context.params;
const shoppingLists = await getAllLists(userId);
return {
props: {
shoppingLists,
},
};
}
I am using Stripe in my NextJs project and have tried to get customers list in my app but have not succeeded. If anyone knows how to get it, please instruct me on how to do that.
This is my code:
import { loadStripe } from "#stripe/stripe-js";
async function getStripeCustomers(){
const stripe = await loadStripe(
process.env.key
);
if (stripe) {
// there was a toturail for node.js like this.
console.log(stripe.customers.list())
}
}
useEffect(() => {
getStripeCustomers()
}, []);
I think you should do this logic in backend so create a route in api folder then try this code.
// api/payment/get-all-customers.js
import Stripe from "stripe";
export default async function handler(req, res) {
if (req.method === "POST") {
const { token } = JSON.parse(req.body);
if (!token) {
return res.status(403).json({ msg: "Forbidden" });
}
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET, {
apiVersion: "2020-08-27",
});
try {
const customers = await stripe.customers.list(); // returns all customers sorted by createdDate
res.status(200).json(customers);
} catch (err) {
console.log(err);
res.status(500).json({ error: true });
}
}
}
Now from frontend send a POST request to newly created route.
So I have a simple middleware that listens for errors and removes details to make them friendlier:
import {
isHttpError,
Status,
isProduction,
Middleware
} from "../deps.ts";
import { Context } from "./../types.ts";
const errorMiddleware: Middleware = async (ctx: Context, next: () => Promise<unknown>) => {
try {
await next();
} catch (err) {
let message = err.message;
const status = err.status || err.statusCode || Status.InternalServerError;
/**
* considering all unhandled errors as internal server error,
* do not want to share internal server errors to
* end user in non "development" mode
*/
if (!isHttpError(err)) {
message = !isProduction
? message
: "Internal Server Error";
}
if (!isProduction) {
console.log(err);
}
ctx.response.status = status;
ctx.response.body = { status, message };
}
};
export { errorMiddleware };
I'm trying to write a test that throws a random error and checks to see if the middleware is adjusting the message as expected.
This is what I've tried:
Deno.test({
name: "Middleware changes error message to Internal Server Error",
async fn() {
const mw1: Middleware = async (_context, next) => {
await next();
};
let caught: any;
const mockContext = testing.createMockContext();
const mockNext = () => {
return new Promise<void>((resolve) => {
setTimeout(() => {
mockContext.throw(500, "Hi there");
resolve();
}, 50);
});
};
try {
await mw1(mockContext, mockNext); // hoping this throws the error into the next middleware
await errorMiddleware(mockContext, testing.createMockNext());
} catch (error) {
caught = error;
}
assert(caught instanceof httpErrors.InternalServerError);
assertEquals(caught.message,"Internal Server Error");
},
});
The test doesn't work, I just get this error:
Is there a different way I should be approaching the tests? I've tried to look at the tests in the oak library to see if there's similar examples but I couldn't seem to find any.
It's not possible to reproduce your issue because you have not provided all of the necessary code, so here's a similar, self-contained example to demonstrate how to test an error renaming middleware with Oak. Also, see the internal Oak middleware module tests for reference.
so-69820660.test.ts
import { delay } from "https://deno.land/std#0.113.0/async/mod.ts";
import {
assert,
assertEquals,
} from "https://deno.land/std#0.113.0/testing/asserts.ts";
import {
composeMiddleware,
httpErrors,
Middleware,
Status,
testing,
} from "https://deno.land/x/oak#v9.0.1/mod.ts";
const renameError: Middleware = async (_, next) => {
try {
await next();
} catch (exception: unknown) {
if (!(exception instanceof Error)) throw new Error(String(exception));
exception.message = "Custom error message";
throw exception;
}
};
Deno.test({
name: "Middleware renames error message",
async fn() {
let exceptionWasCaught = false;
const delayAndThrow: Middleware = async (ctx) => {
await delay(50);
ctx.throw(Status.InternalServerError, "Uh oh");
};
const catchAndAssert: Middleware = async (_, next) => {
try {
await next();
} catch (exception: unknown) {
exceptionWasCaught = true;
assert(exception instanceof httpErrors.InternalServerError);
assertEquals(exception.message, "Custom error message");
}
};
const mw = composeMiddleware([catchAndAssert, renameError, delayAndThrow]);
await mw(testing.createMockContext());
assert(exceptionWasCaught);
},
});
% deno --version
deno 1.15.3 (release, x86_64-apple-darwin)
v8 9.5.172.19
typescript 4.4.2
% deno test so-69820660.test.ts
running 1 test from file:///Users/deno/so-69820660.test.ts
test Middleware renames error message ... ok (65ms)
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (261ms)
I am trying to use firebase/firestore with Nuxt asyncData() and for some reason my data is not being returned at all. No errors in console, either.
Anyone spot anything?
Here is my code:
index.vue
async asyncData({ app, error }) {
const docRef = await app.$fireStore.collection('photos')
try {
docRef.onSnapshot((snapShot) => {
const snapData = []
snapShot.forEach((doc) => {
snapData.push(doc.data())
})
return {
snapData
}
})
} catch (e) {
error({
statusCode: 503,
message: 'Unable to fetch posts at this time. Please try again.'
})
}
},
Here is my devtools screen:
I seem to have gotten it working. I had to write it like so:
async asyncData({ app, error }) {
const photosArr = []
const docRef = await app.$fireStore.collection('photos')
try {
docRef.onSnapshot((querySnapshot) => {
querySnapshot.forEach((doc) => {
photosArr.push(doc.data())
})
})
return {
photos: photosArr
}
} catch (e) {
error({
statusCode: 503,
message: 'Unable to fetch posts at this time. Please try again.'
})
}
},