So, if a new user tries to sign up with an user account that already exists, MongoDb responds with a 11000 error code
In Express, that can be handled like this:
async function signup(req, res, next){
try{
// some stuff
}catch(err){
if (err.code === 11000) {
err.message = 'Email is already taken.';
res.statusCode = 409;
}
return next(err);
}
}
For this example, I decided to respond with a 409 http status code.
However, I am not sure if it's a good approach to handle several different codes from MongoDB and assigning an http status for each of them.
What other solutions am I missing?
You can return specific responses to common errors that you might come across.
But it really comes down to how specific you want to be. You also need to consider is it really worth it to customize the response for each and every single error that can occur. Some of them might never happen depending on your configuration.
For example, ncompatibleShardingConfigVersion will never happen if you are not using a sharded cluster.
Furthermore, if the error message is supposed to be displayed at the frontend, the users don't really care about the what, why, and how of an error. What he/she knows is that it doesn't work and he/she is not happy.
You have several options:
Using conditionals like what you are doing now. Perhaps create a custom error constructor and put the conditionals in it to avoid having to repeat yourself in every single function call.
Send a generic error message to the frontend with status code 500. Log the whole error object at the backend so you can know what went wrong. You are the person who actually cares about the why, what, how, when of an error.
Personally, I will go with option 2.
Related
Please tell me what is the problem in this code.
let walletAddress = request.body.walletAddress;
if (walletAddress.length < 34) {
return response.status(400).json({
walletAddress: 'Invalid Wallet Address'
});
}
There's not enough code include or enough evidence of debugging and data form debugging to know for sure what is going on.
The very first thing you would do is do a:
console.log(req.body)
at the beginning of your request handler and see what it contains. This is basic debugging that you should do before you come here. It appears there is apparently no walletAddress property in req.body.
Then you have to figure out why that is. Either you aren't sending the right kind of request from Postman (either it's not a POST or it doesn't have the right data with it or something else is wrong with the request) or you don't have the body-parser middleware installed to read and parse the body to actually fill in the properties on req.body from the POST data.
For help with either of these, show us the rest of your server set up code so we can see where body-parser middleware is or isn't installed and what your request handler looks like. And, show us the exact request you're sending from Postman.
I'm working with an express application. There are some express routes, as
server.get('*' , ... )
etc. which perform some common operations: authentication, validation... etc.
they also decorates the response with meaningful information: i.e. in every request to the server it gives not only the expected json/html, but also information regarding the user, some app metadata that the front-end consumes etc. etc.
Let's say all this extra metadata cames in a field called extradata in every request to the server.
Now, there is a bug that is causing a problem: instead of returning its expected response (a json with a bunch of system logs), is sending only this extradata field.
I'm pretty confident the problem is in one of the middlewares, because that code that sends the response in this case is really simple, it's just a res.send() of a json. So I believe this part of the app is requiring some module that sets a middleware which causes the error. There are a lot of global vars and implicit parameters in the app so is really difficult to debug it manualluy.
I attempted to bypass such middlewares programmatically, like:
delete server._router.stack[2];
but is causing an TypeError: Cannot read property 'route' of undefined and thus preventing my app to build: sure this is not the way to go.
so, is there a way to programmatically ignore or bypass express routes that are yet set?
Even better, is there a way to programmatically tap into express middlewares and log every request and response?
(afaik, there are libreries like morgan that logs every request, but I don't think they apply to this case since I need to discriminate between middlewares).
What I generally do is simply use the next method. You can access it by simply passing it to the callback function. Something like:
app.use(function(req, res, next) {
if(...) {
next();
} else {
...
}
}
What this is going to do is go to the next middleware.
So if I understand correctly, you can check what you exactly need in the if-statement and do things accordingly.
What I would suggest is you read the Express API documentation, especially the section about middleware, which you can find here. Moreover, try to isolate the suspects and solve the issue by removing the problem, rather than deleting handlers and trying to solve the problem the easy way.
Our product is going to live soon, and some of the users are testing on it. Sometimes, they got the exception randomly and currently, the only way for me to know about it is ssh to the server and scan thousand lines of log in order to know the exception.
In my 8 hours working stack (Java, Spring, ...), I can configure the exception through Aspect, Interceptor in order to watch the exception and notify about the exception through email (sending log file, exception reason to me).
How can I do that in Meteor ? What is the error handling strategy ? Is there any thing that close to Interceptor/Aspect in Meteor so I can inject the email sending during the exception ? I don't really want to use any external service to watch our app for the performance / exception
Some packages look promising. Winston with the email transport kinda suit my needs. I will update this answer if I come up successfully with that
You can configure Email alerts for exception handling.
Add package called email using meteor add email
use callback method
Meteor.call('methodname', function (err, data) {
if (!err) {
//perform some action
}
} else {
console.log(err);
Meteor.call('sendEmail',"error in this method");
//here sendEmail methods send email about the error
}
});
I am quite unsure how I should properly handle uncaught exceptions that occurs in my node.js/express app. Right now I have an Express app that will send all caught errors to an Express error handeler using next(err):
function(err, req, res, next) {
// Do something with the error
}
This seems to work all fine and well for errors I have anticipated. For instance a database connection not working, essentially all things that will return a callback(err). Thought problem occurs when I want to preform a background task, which will finish after the response has been sent. For instance:
app.get('/url', function(req, res) {
BackgroundTask.run() // Here an uncaught exception occurs, for instance a bug
res.send('Running your background task')
}
The background modules that I want to run aren't express related (no use of req,res) and upon a caught errors they will use a custom in errorHandeler that will send the error to some error reporting service. However when an uncaught exception occurs in one of these background tasks I have no clue how to send the error to my error report service (Raygun in this case). The only thing that seems to work is to add a process.on('uncaughtException') event listener. However almost every post on the subject describes the latter a 'bad' or crude way of doing things. They seems to recommand using node domains however I don't really see how I can implement these for background tasks.
I use process.on(uncaughtException), because all you're really trying to do is catch the output from the error and shut the server down gracefully (and then restart). I don't see any reason to do anything more complicated than that, because by nature of the exception, you don't want your application doing anything else in that state other than shutting down.
Domains are an alternative way of dealing with this, but it's not necessarily better than using the process handler, because you're effectively writing custom logic to handle things that you aren't anticipating. It does give you finer granularity in terms of what your error handler does for different error types, but ultimately you're still potentially running your application in an unknown state after handling it. I'd rather have my application log the exception, shut down, and then i'll fix the error so it never happens again, rather than risking my user's data on a domain solution which may or may not have handled the error correctly, depending on the nuance of the error it encountered.
I am writing a Backbone application which should interface to a REST API.
My problem arises when a user deletes a model that has already been deleted by someone else. In my opinion, the backend should just return success (200), as the model is deleted anyway. But the people developing the server side have a different opinion, hence what I get is a 404. For comparison, when the request actually fails - hence the model is still alive - the response code is 400, or possibly 401 for authorization issues.
Since I get an error, I actually do not remove the model. What I am trying to do is modifying this behaviour: if I get a 404 error while deleting a model, it should be treated as success. But I am not really sure what is the most convenient way to handle this.
Ideally I would like to avoid putting this logic inside model.destroy. This would lead to a repetition. I could put this inside a destroy method of a superclass, but models override this method anyway, each one with its own logic, so it gets messy. I would prefer that at this point the model.destroy methods received a success, not knowing that the actual response was a 404.
On the other hand, I am not sure how to put this logic inside Backbone.sync, short of rewriting the whole function.
What is the most transparent way to transform all 404 responses to DELETE requests into success?
It's a hack, but should do the trick:
model.destroy({
error: function(model, resp, options) {
if (resp.status == 404) {
resp.status = 200;
options.success(model, resp);
}
}
})
Btw, as of Backbone 0.9, destroy() and create() are optimistic.