How return custom errors in mongoose? - node.js

Having a mongoose model is it possible to add error handling directly to the model using .on('error) listener?
My goal is to add custom error messages to the incoming errors depending on their origin. Also I was thinking about changing error messages to make them more user friendly.
this.model.on('error', function(error) {
if (someCondition)
error = new ApolloError('Custom message', 'NOT_FOUND')
return error;
});
Basically, I want to to receive an error with a code NOT_FOUND and a custom message whenever mongoose throws an error that satisfies some condition. Any help would be appreciated.

I've came up with the following solution, which is to use toApolloError util found in apollo-server-errors
this.model.on('error', function(error) {
toApolloError(error, 'USER_INPUT_ERROR');
});

Related

Mongoose and postman error in method model.find()

This is the screenshot of my Javascript codeThis is the screenshot of postman
app.get("/students/:id",async(req,res)=>{
try {
const _id=req.params.id;
const studentData=await Student.findById(_id);
console.log(studentData);
if(!studentData){
return res.status(404).send();
}else
res.send(studentData);
}
catch(err) {
res.send(err);
}
});
For this id case I am able to find the value in database.
But if I am using model.find({name:name}) as per screenshot ,I am getting some error in postman.Can anyone help me to solve the issue.
it seems you have two conflicting routes, from your code above I see you have a get route for /student/:id and from the screenshot you have another get route for /student/:name these two routes cannot exist together as express is going to pick the first one you defined.
I suggest changing them to /student/id/:id and /student/name/:name.

express-restify-mongoose error propogation

I am having a problem serving up error messages using express-mongoose-restify.
My schema has a hook like
myschema.pre('save', function(next){
// If validation fails
next(new Error('failed to validate model'))
})
For error handling I have (something similar to) the following code
resify.serve(express.Router(), mongoose.model('myschema', {
onError: function(err, req,res,next){
console.log(err)
res.status(400).json(err)
}
})
The output to the console when validation fails is as follows:
{ [Error: failed to validate model] statusCode : 400 }
In my client I have the following (jquery) ajax error handler:
$( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
console.log(jqxhr)
console.log(thrownError)
});
thrownErorr is equal to "Bad Request" and jqxhr has reseponseText: "{"statusCode" : 400}" similar (but parsed to JS) for the responseJSON. The message failed to validate model is not being sent to the client. I think that I am misunderstanding the type of object that err is in my sever side error handler. Any thoughts? Thanks in advance!
This is one of those cases where writing the question made me think of the right question to ask myself in order to answer it.
The V8 error object that is use by node does not send the additional information such as the stack, message etc when converted to JSON. My problem was solved by reading up on the properties of the Error object here.
In particular using the following handler, the error is successfully relayed to the client
onError : function(err, req, res, next){
res.status(400).json({
message : err.message,
stack : err.stack
})
}

How to promisify my Class in nodejs

I am using bluebird to implementing promisify in my custom lib. I have follwing lib
user, lib-1, lib-2 etc
On user registration, from my user router
// user_router.js
var user = new User();
var lib1 = new Lib1();
var lib2 = new Lib2();
// I am expecting, all method will be async by following 3 lines!
Promise.promisifyAll(user);
Promise.promisifyAll(lib1);
Promise.promisifyAll(lib2);
user.validationAsync(payload)
.then(function(result_from_validation) {
return lib1.validationAsync(payload);
})
.then(function(result_lib1_validation)) {
return lib2.validationAsync(payload)
})
.then(function(result_lib2_validation)) {
// final save
user.registerAsync(payload);
lib1.saveAsync(payload);
lib2.saveAsync(payload);
return {'response-data'}
})
.then(function(response)) {
// send response
res.json('success', 'User successfully created', {});
})
.catch(function(error)) {
//all error will be handled here
//these error will be either throw or by promise rejected.
res.json('error', error.message, {error.stack});
})
In validation method I am throwing errors like
//user_lib.js
// This throw will be handled by router catch. ???
throw Error('Field value is invalid');
In save method mongooes modal also have some validation like user already exist so unable to create user.
function register (payload)
{
// payload data binded on user_modal here
var user_modal = getUserModal(payload);
user_modal.saveAsync()
.then(function(){})
.catch(function(error){
//How to handle error here and send this error to router
})
}
All above is just my expectation. I want to send all response from user_router.js. (My user module already implemented. now need to integrate it by bluebird)
Now Question ::
How can I do it by bluebird ? How to set resolve/reject method on
user object(explicitly) ??
If validation method throw error then it
will be captured by router catch method ???
How can I send any
error/rejection to router's catch from mongooes (see user register
method)?
I hope you will get my points. Thanks in advance!!
You can also share any example link to implement these things.
Now I am using try catch for normal statement and using promise for async error handling!! :) Thanks a lot guyz

Detecting process crashes with New Relic in NodeJS

How do you get New Relic to log errors which crash the process using their New Relic application monitoring? The key things I'm trying to accomplish are to have errors which crash the process still get logged and some way to filter to these errors on the dashboard.
Here's my understanding so far:
New Relic transmits data to their cloud every minute. In the event a uncaughtException occurs, this will result in all of the data currently waiting to be transmitted to be lost.
There is a newrelic.noticeError() which is supposed to take a second argument allowing you to pass custom parameters with an error. New relic gets the error, but not the custom parameters.
Simple Example:
var newrelic = require("newrelic");
var express = require("express");
var app = express();
app.get("/softFail/", function(req, res) {
res.send(500, "softFail");
});
app.get("/hardFail/", function(req, res) {
setImmediate(function() {
throw new Error("I failed");
});
});
app.listen(80);
process.on("uncaughtException", function(err) {
console.error("Uncaught Exception");
console.error(err.stack);
newrelic.addCustomParameter("crash", "true");
newrelic.noticeError(err);
console.log("sending errors to New Relic");
newrelic.agent.harvest(function() {
console.log("send complete, crashing process");
process.exit(1);
});
});
Using that block of code if I call /hardFail/ I'm able to get New Relic to at least log the error. Without the uncaughtException handler I don't get anything to New Relic. The issue is that I can't differentiate between the errors which crash the process, and normal HTTP 500 errors.
Here's something things I've tried:
If I attempt to add { crash : true } to the noticeError call it doesn't seem to have any affect.
I've tried to do domain instead of process.on, that doesn't change the situation.
If I attempt to alter the name of the error, such as err.name = "CrashError" then the error doesn't get transmitted at all.
If I create a custom error type, and then new that, and copy the stack trace on to it, it still reports as type Error rather than the prototype.name of my new error type.

Restangular put() yielding a 404 when updating from a form

Restangular has been throwing me a 404 when sending PUT requests, and I'm not sure why.
I have an Events collection, and I'm getting a single event and updating it in a form.
According to the Restangular docs, when I make a PUT request on the Event, it should route to api/events/:eventId. Instead, I'm getting an error saying it's routing to api/events.
The error:
PUT http://localhost:9000/api/events 404 (Not Found)
Can you see where I'm going wrong? I haven't changed the config on Restangular at all.
Here's my controller:
var restEvent = Restangular.one("api/events", $routeParams.eventId);
restEvent.get().then(function(eventData) {
// the eventData is successfully coming through
$scope.thisEvent = Restangular.copy(eventData);
// $scope.thisEvent is modified in the form
// updateEvent() runs when my Event form is submitted
$scope.updateEvent = function() {
$scope.thisEvent.put();
};
});
Here's my Express update routes:
// update route -------------
app.route('/api/events/:event_id')
.get(events.show)
.put(events.updateEvent);
Any suggestions?
This is actually an issue with Restangular/Mongo. Restangular defaults its primary key to "id", whereas Mongo uses "_id". When Restangular tries to append "id" from the Event object to api/events, it can't find "id" and only routes to api/events.
Here's the code that the Restangular docs suggest, and that solves this issue:
app.config(function(RestangularProvider) {
RestangularProvider.setRestangularFields({
id: "_id"
});
});
It could be browser problem, I would recommend to go for this for PUT and PATCH:
app.config(function(RestangularProvider) {
RestangularProvider.setMethodOverriders(['put', 'patch']);
});

Resources