MongoDB : "message": "Cannot read properties of undefined (reading 'findById')" - mongodb

I am creating api i get this error in postman "message": "Cannot read properties of undefined (reading 'findById')"
async function getCustomer(req, res, next) {
let Customer
try {
Customer = await Customer.findById(req.params,id)
if (Customer == null) {
return res.status(404).json({ message: 'Cannot find Customer' })
}
} catch (err) {
return res.status(500).json({ message: err.message })
}
res.Customer = Customer
next()
}
any help please?

The problem is
let Customer
When calling Customer.findById() the local Customer will be called (the one declared with let).
Name the customer with a small letter i.e
let customer
customer = await Customer.findById()...

Related

Express and MongoDB, how to manualy throw the error in the route controllers?

I'm new to the Express, and I'm trying to apply some error handling at the top level.
In my controllers file, I have a controller to get all tours.
exports.getAllTours = async (req: Request, res: Response) => {
//Execute query
const features = new APIFeatures(Tour.find(), req.query)
.filter()
.sort()
.limitFields()
.paginate();
// Endpoint: http://localhost:8000/api/v1/tours
// Enter a wrong URL here will not even trigger the console.log function.
// But I want to throw the error right here, not in the app.all('*')
console.log("features", features);
if (!features) {
throw new NotFoundError("Tours Not Found");
}
//same problem here.
const tours = await features.query;
console.log("tours", tours.length);
if (!tours) {
throw new NotFoundError("Tours Not Found");
}
res.status(200).json({
status: "success",
result: tours.length,
data: {
tours,
},
});
};
I have a CustomError class that extends the Error class like this.
const httpStatusCode = require("./httpStatusCode");
class CustomError extends Error {
constructor(message: string, statusCode: number, description: string) {
super(description);
//Object.setPrototypeOf(this, new.target.prototype);
this.message = message;
this.statusCode = statusCode;
}
}
module.exports = CustomError;
class NotFoundError extends CustomError {
constructor(message, statusCode) {
super(message, statusCode);
this.message = message;
this.statusCode = httpStatusCode.NOT_FOUND;
}
}
module.exports = NotFoundError;
Also an error handling middleware:
import { NextFunction, Request, Response, ErrorRequestHandler } from "express";
module.exports = (
err: Error,
req: Request,
res: Response,
next: NextFunction
) => {
err.statusCode = err.statusCode || 500;
err.status = err.status || "error";
res.status(err.statusCode).json({
status: err.status,
message: err.message,
});
};
In the end, I use the errorHandler middleware in the app to catch all the errors.
However, the problem is all the errors in the getAllTours controller will not be thrown, instead, they will be thrown in the app.all():
app.use("/api/v1/tours", tourRouter);
app.all("*", (req: Request, res: Response) => {
throw new NotFoundError("Page Not Found");
//next(new AppError(`Can't find ${req.originalUrl} on this server`, 404));
});
app.use(errorHandler);
I know since the endpoint has been changed and thrown in the app.all() make sense. But how can I manually throw an error in the getAllTours controller?
I use express-async-error so I could use the throw keyword in the async function.
I figure it out.
Handle Express async error
I had no idea Express version 4 could not handle the async errors by simply throwing a new error. I'm still not sure if Express Version 5 as it now could handle it.
But I use ExpressJS Async Errors to solve this issue in the end.

How to find the field that caused the error

I am trying to find the field that has an error as described on this page:
https://www.prisma.io/docs/reference/api-reference/error-reference
More specifically: PrismaClientKnownRequestError, meta Additional information about the error - for example, the field that caused the error: { target: [ 'email' ] }
I can not seem to log meta.target, instead I get undefined.
This is the sample code from the docs.
import { PrismaClient, Prisma } from '#prisma/client'
const client = new PrismaClient()
try {
await client.user.create({ data: { email: 'alreadyexisting#mail.com' } })
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
// The .code property can be accessed in a type-safe manner
if (e.code === 'P2002') {
console.log(
'There is a unique constraint violation, a new user cannot be created with this email'
)
}
}
throw e
}
How do I get access to target?
Many thanks
Paul

"Cannot read property 'uid' of undefined" error - Plaid link token

I'm getting a "Cannot read property 'uid' of undefined" when trying to create a plaid token....I have spent like 3 days trying to make it work.
does anybody knows how to fix it?
Cloud function to get Plaid token
//PLAID - create link Token plaid Nat
const plaid = require("plaid");
exports.createPlaidLinkToken = functions.https.onCall(async (data, context) => {
const customerId = context.auth.uid;
const plaidClient = new plaid.Client({
clientID: functions.config().plaid.client_id,
secret: functions.config().plaid.secret,
env: plaid.environments.development,
options: {
version: "2019-05-29",
},
});
return plaidClient.createLinkToken({
user: {
client_user_id: customerId,
},
client_name: "Reny",
products: ["auth"],
country_codes: ["US"],
language: "en",
})
.then((apiResponse) => {
const linkToken = apiResponse.link_token;
return linkToken;
})
.catch((err) => {
console.log(err);
throw new functions.https.HttpsError(
"internal",
" Unable to create plaid link token: " + err
);
});
});
swift function
class func createLinkToken(completion: #escaping (String?) -> ()){
//this is the firebase function
Functions.functions().httpsCallable("createPlaidLinkToken").call { (result, error) in
if let error = error {
debugPrint(error.localizedDescription)
return completion(nil)
}
guard let linkToken = result?.data as? String else {
return completion(nil)
}
completion(linkToken)
}
}
The only .uid in your code is in this line:
const customerId = context.auth.uid;
So it seems like context.auth is undefined. In the Cloud Functions code you can handle this with:
exports.createPlaidLinkToken = functions.https.onCall(async (data, context) => {
// Checking that the user is authenticated.
if (!context.auth) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
}
const customerId = context.auth.uid;
...
The new code here comes from the Firebase documentation on handling errors in callable Cloud Functions.
You'll also want to check if the user is signed in in your Swift code.

Pushserver isn't waiting for promise answer

I have this push server which sends push notifications to devices and logs the response to a json. The code goes:
push.js
module.exports.sendPushSubscription = async (post, recipient, p256, auth) => {
console.log("Mandando PUSHES");
const subscription = {
endpoint: `https://fcm.googleapis.com/fcm/send/${recipient}`,
expirationTime: null,
keys: {
p256dh: `${p256}`,
auth: `${auth}`
}
}
console.log(subscription);
error = webpush.sendNotification(subscription, JSON.stringify(post))
.then(() => {
console.log("Notificación enviada");
return "Sent!";
})
.catch(err => {
return err;
});
await Promise.all(error);
return error;
};
routes.js
recipients = recipients.split(',');
p256 = p256.split(',');
auth = auth.split(',');
let err = "";
for(var i=0;i<recipients.length;i++) {
err = "Trying";
err = push.sendPushSubscription(post, recipients[i], p256[i], auth[i]);
post.recipients.push({
recipient: recipients[i],
error: err
})
}
rsp.json(post);
However, despite the code might suggest the sendPushSubscription function should wait for the promises to end (it's usually only one) and return either Sent! or the error itself, the json always adds the recipient and an empty error. No matter if it succeeds or fails, the answer is:
"recipients": [
{
"recipient": "d96UkANUtAo:APA91bF1-...",
"error": {}
}
Any ideas? Thanks in advance.
Best regards,
Emiliano

Mongodb errors specific code handling

I am trying to output specific messages on specific responses.
Here is my code:
.post(function(req, res) {
var user = new User(req.body);
user.save(function(err) {
if(err) {
if(err.code == 11000)
res.status(409).json(customHTTPcodeReponses.exists(req.body.email));
};
User.findById(user._id, function(err, createdUser) {
res.status(201).json(customHTTPcodeReponses.created(createdUser));
});
});
});
Flow:
Posting data. I get 201.
Posting same data again. I get 409.
Posting same data again. I get "Could not get any response (POSTMAN)"
Console error:
_http_outgoing.js:335
throw new Error('Can\'t set headers after they are sent.');
[nodemon] app crashed - waiting for file changes before starting...
What could cause this?
Add the User.findById code within an else statement.
user.save(function(err) {
if(err) {
if(err.code == 11000)
res.status(409).json(customHTTPcodeReponses.exists(req.body.email));
}else{
User.findById(user._id, function(err, createdUser) {
res.status(201).json(customHTTPcodeReponses.created(createdUser));
});
}
});
or add a return to the 1st response:
if(err.code == 11000)
return res.status(409).json(customHTTPcodeReponses.exists(req.body.email));