Below is the piece of code for my route.patch function that I defined for /:productId
route.patch('/:productId',(req,res,next)=>{
const id = req.params.productId;
const updateOps = {};
console.log(req.body);
for (const ops of req.body) {
updateOps[ops.propName] = ops.value;
console.log(updateOps);
}
res.status(200).json({Message: 'Hi'});
});
console.log(req.body) before the for loop is working but the console.log(updateOps) inside for loop is not working. And the even the res.status(200).json({Message: 'Hi'}); is not working . I am getting a route not found error.
Basically everything before for loop is working and everything after for loop is not working.
Can you please let me know where am I doing wrong. Is it the way I use for loop inside route.patch is wrong? Any help is highly appreciated.
Thanks
Answering your question regarding the error-handling from the comments. You have the following middlewares:
app.use((req, res, next) => {
const error = new Error('Not found');
//console.log(error.status) //console.log(error.message)
error.status = 404; //console.log(error.message)
next(error);
});
app.use((error, req, res, next) => {
res.status(error.status || 500);
res.json({
error: {
message: 'Route not found'
}
})
});
So for every request an error-object will be created which you assign status 404 and pass it on to the next middleware. There you send the error response and since the status is already set to 404 this status is used.
Actually you should just remove the first middleware where you create the error, as this would be done for every request. Express already handles requests to routes that do not exist and will return a 404 not found response. You can keep the second middleware to handle any other unhandled errors though (you should change the error message though :))
Related
i want send request to an api but i have 404 erro and i have nothing in network
can you help me?
my code:
loginMethod() {
const config = {
userName: "test#gmail.com",
password: "1234test",
};
return new Promise((resolve) => {
ApiService.post("api/authentication/login", config)
.then(({ data }) => {
console.log(data);
resolve(data);
})
.catch(({ response }) => {
console.log(response);
});
});
},
and ApiService function:
post(resource, params) {
console.log(params);
const headers = {
"E-Access-Key": "bb08ce8",
};
return Vue.axios.post(`${resource}`, params, { headers: headers });
},
Based only on what I can see in your code, you are not telling axios the complete URL if I'm right about it, and you didn't declare it somewhere else do this:
axios.post('yourdomain.com/api/authentication/login',params)
or
axios({
url:'yourdomain.com/api/authentication/login',
method:post,
data:{}
})
or
in your main js file or any other file that you import axios (if you are sharing an instance of it globali):
axios({baseurl:'yourdomain.com'})
and then you don't need to write the complete url everywhere and just insert the part you need like you are doing now and axios will join that address with the baseurl,I hope it helps
I guess the URL "api/authentication/login" might be wrong and the correct one would be "/api/authentication/login" that starts with /.
404 error means the resource referred by the URL does not exist. It happens when the server has deleted the resource, or you requested a wrong URL accidentally, or any wrong ways (e.g. GET vs POST)
To make sure if you were requesting to the correct URL (and to find where you're requesting actually), open Google Chrome DevTools > Network panel. You might need reload.
The url api/xxx is relatively solved from the URL currently you are at. If you were at the page http://example.com/foo/bar, the requested URL becomes http://example.com/foo/bar/api/xxx. Starting with / means root so http://example.com/api/xxx.
This answer might help to understand the URL system: https://stackoverflow.com/a/21828923/3990900
"404" means your API Endpoint is not found. You need to declare the location of your API Endpoint exactly. For example: http://localhost:8080/api/authentication/login.
Basically, the question is do I need to use next(err) when encountering any errors? The nodejs error documentation says it is fine to use a standard sort of if(err) else... for asynchronous callbacks and EventEmitters, as long as the error isnt handled with a try-catch block for non async-await functions, as it will cause crashing. If I do need to use them, what is to prevent the next() function being called multiple times in the same handler for different asynchronous operations? Wouldnt using the default error handler cause headers to be sent multiple times and cause an error of its own when using event emitters ?
Apologies if the question has been asked, its just I cannot find a specific answer to why usage of express.js error handling is preferred.
If you are asking if you need to use an explicit next(err) in a handler,
e.g.
app.get('/someurl', (req, res, next) => {
//do something - whoops had an error
next(err);
})
No, the above is not required in a handler.
The only time you would need to explicitly wrap or pass on the error is if you have, for example, used a try/catch and are not handling the error condition itself in the handler, i.e. not returning a response in the handler (Not sure why you would want to do that).
What will happen above when an error occurs in the handler, express will continue on through the middlewares until it finds a handler that will deal with your error.
If there are none, it will exit.
So to use a global error handler, you could write your app like the following and not worry about next(err) in each handler function.
app.get('/route/one', async (req, res) => {
// do something that could throw an error
const result = await aFunctionThatCouldThrowAnError();
// No error handling in this function
res.json({ result });
});
app.get('/route/two', (req, res) => {
res.json({ hello: 'world-two' });
});
// A Global Error handler
app.use((err, req, res, next) => {
//handle all errors here
if(err) {
res.status(500).send('some error message')
}
res.status(404).send('not found');
});
Note that the order of middlewares is important, so the global error handler should be applied last.
Here is the background of the question : I'm following the kick-off-koa using Koa 2. But the exercises in the kick-off are designed for Koa 1. I've created an issue for this problem of Koa 2 : Task of error handler with Koa 2 cannot pass.
For short, my problem is how to display a custom error page when a 500 error happens.
Here are the codes :
// error handler middleware
function errorHandler(ctx, next) {
try {
return next();
}
catch(err) {
ctx.status = err.status || 500;
// I would like to display the custom message as follows
ctx.body = 'Oops! internal server error';
// with emitting the error event, don't work
// ctx.app.emit('error', err, ctx);
}
}
// to generate error
app.use(router.get('/error', ctx => {
ctx.throw('oops', 500);
}));
But my page of error is always displaying as "Internal Server Error", which is the default message. It seems that ctx.body = 'Oops! internal server error'; couldn't modify the page.
Thanks for the helps!
If you are using Koa2, you don't have to return inside middleware, instead, use await. And by the way, your middleware function MUST be an async function.
Here is an example of a combined 404 and 500 middleware:
app.use(async (ctx, next) => {
try {
await next()
if (ctx.status === 404) ctx.throw(404)
} catch (err) {
console.error(err)
ctx.status = err.status || 500
ctx.body = errorPage.render({ // Use your render method
error: err,
})
}
})
// Your normal routes here
First, Koa awaits for the next middleware in the chain (which is your normal routes). If nothing is found or an error occurred, the middleware chain goes backwards and the next line is executed, which throws a 404 and its captured inside the catch.
Now in the catch statement, you can get either 404, 500 (by default) or 5xx if other error occurred.
The body of the page is also set with a render of your template and passing the error to the template so you can make use of it.
You don't have to emit the error as this is the last catch in the chain.
I am using expressjs to implement api calls for my app. Much of the time I don't want to send back extra data in the body however expressjs sends the http status text in the response if you don't specify a body.
For res.send(200); outputs OK in the body, res.send(400); outputs Not Found and so on.
The problem is that my UI is expecting well formatted JSON or an empty body, and the bare strings break this convention. The work around I've found for now is to send res.send(200,{}); to send an empty object, but that's a pain in the butt to do that for every api call.
Is there any way to get around express returning this bare text on an empty response?
Without modifying the express library itself, you can create a middleware function that extends the functionality of res.send.
You can modify res.send so an empty string is added to its arguments when invoked only with a status code. This will prevent the name of the status code from being sent.
app.use(function(req, res, next) {
var send = res.send;
res.send = function() {
if (arguments.length == 1 && typeof arguments[0] == 'number') {
arguments[arguments.length++] = '';
}
return send.apply(res, arguments);
};
next();
});
app.get('/good', function(req, res) {
res.send(200);
});
app.get('/not-found', function(req, res) {
res.send(404);
});
How can I implement a custom error handler in Express using CSRF middleware after users click the back button in browser and resubmit the form? By default Express return a 403 page with lots of stack traces. I want to replace it by for example redirecting user to a custom error page. How can I do that?
Here are some examples of writing custom error handlers in Express: https://github.com/visionmedia/express/blob/master/examples/error-pages/index.js
Here are the custom error handlers I use: Error handling in an Express route
You might also want to consider modifying connect to return a different code than 403 when CSRF fails. You can change it here: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js#L82
You might choose 428 Precondition Required. The full list is here: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
That way, you could have a special message shown only for CSRF failures.
Like any other well designed middleware csurf passes the error to next. So it's possible to react on the raised error in the following way:
var csurf = require('csurf')();
app.use(function (req, res, next) {
csurf(req, res, function (err) {
if (err) {
// do what ever with err
} else {
next();
}
});
});