Browser not showing Internal Server Error HTML Page with status 500 - node.js

I've two components in my application. A frontend which is built on Angular and backend built using express. I'm using the Nest.js framework in the backend.
I have an http-exception.filter.ts file which takes care of any thrown exception. So far, I've been handling Internal Server Error in the application this way.
if(exception.getStatus() === 500) {
response
.status(500)
.json({
status: '500',
code: 'INTERNAL_SERVER_ERROR',
message: 'Internal Server Error'
});
}
But, now an HTML page has been designed showing Internal Server Error message. All I need to do to render that page is to hit the URL /ui/internal-server-error. So, I tried to that using the code below.
response
.status(500)
.redirect('/ui/internal-server-error');
The page loads when a case of internal server error occurs, but the problem is I'm not getting 500 status when I'm reading the network logs in the browser. Instead, I'm getting 304 Not modified status.
Could anyone please point me in the right direction? I want to show the error page along with status code 500 and the UI page needs to come from Frontend only as I've no access over it.

When redirect is called, it sets the status, so the 500 is replaced.
From the express docs (relevant as NestJS uses Express by default):
Redirects to the URL derived from the specified path, with specified status, a positive integer that corresponds to an HTTP status code . If not specified, status defaults to “302 “Found”.
res.redirect('/foo/bar')
res.redirect('http://example.com')
res.redirect(301, 'http://example.com')
res.redirect('../login')
Add the desired status as an argument to redirect.

Related

Express server Error 400 is not returning json message

I am submitting a form and if the form id already exists in the database, I am returning status 400 with a message saying that the form exists.
res.status(400).send({
status: 400,
message: "Form exists"
})
When I read the response sent back from my express server, I am getting Bad request message instead of the custom message object that I am returning. If I replace res.status(400) with res.status(200), I am getting the expected custom message object.
Weird enough, I can get the custom message object when making the server call in development environment. I get Bad Request message from my production server and I don't know why the response is different when the environment is different. I am hosting this server on IIS Manager v10
So my question is should I use status code of 200 instead of 400 in this scenario? Is there a way to return a custom message from status 400? Based on my understanding, I should use 4xx status code if there is a client input errors eg there is already an existing ID or invalid inputs.
Edit: This is my code from my React app.
axiosInstance
.post("/form/some-endpoint", formData)
.then(function () {
navigate(ROUTE_SUCCESS_PAGE);
})
.catch(function (error) {
// eslint-disable-next-line no-console
console.log(error);
alert(error.response !== undefined ? error.response.data.message : error.message);
});
This is the actual screenshot of the response from prod server (I console log it)
But in development environment, I am getting the response that I wanted.
Postman response from Prod server:
<system.webServer>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
Adding the <httpErrors existingResponse="PassThrough" /> to the server's web.config file on IIS Manager resolved my issue. Based on my understanding, bypassing the http error handler and not letting IIS to send its response is the solution that I need.
should I use status code of 200 instead of 400 in this scenario
TLDR: It depends on the usage.
If your intent is to Update a form, like using a PUT request, you should require an id and if that id does not exist, return 404.
If you are looking to Create a new form, like using a POST request, with an id or other meta data and one already exists matching the id or meta data (e.g. groupId), then 400 is fine but it could be better to use 409 stating that there is a conflict with the existing state, that being a preexisting form id or meta data. Though you don't often pass an id to a POST create request.
The full list of codes is a great place to start, but sometimes it helps to see how certain codes are used in production APIs. A good place to look is the GitHub API which shows the possible status codes for each endpoint along with a description. Take the Pulls API for example, just searching for 40 on the page gives you a lot of insight about when certain codes are used.
Comparing these statuses with your example, if you look at the PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge route, they use 409 whenever the state is not matching as they describe...
Conflict if sha was provided and pull request head did not match
This seems similar in nature to the POST request described above.
At the end of the day the crucial part is to get in the correct grouping (i.e 2xx, 4xx, etc.) after that it's more about being consistent across your API than matching the codes to exact best option. Also everyone is different and some may choose different codes for the same use case.
As far as changing the response itself on 400 status, you should be able to achieve this by setting statusMessage directly and then call res.end.
function(req, res) {
res.statusMessage = "Form exists";
res.status(400).end();
}
Also see https://stackoverflow.com/a/36507614/6943587

How can I return server side error to the client's HTML page in Express/node js?

I am creating an web app I which the user requests to create an account. The request from client's page will reach the server and query the database. Now what is the proper way of displaying User already exists error in my registeration page. In short, how can I send server side errors to my clients in Node JS?
There are some options to get what you need. The approach that I would not follow will be using the http protocol and sending a 500 response for example.
One good approach would be creating a status and a message fields in your response.
You could use code 200 for the sucessful requests and a different code for the rest. You could have a dedicated code to inform the api user that the backend coud not insert the data.
Example response:
{
code: 789
message: "User could not be inserted"
...
}

passport-twitter returns "Failed to load resource: the server responded with a status of 500 (Internal Server Error)"

I am stuck trying to solve the problem, but ended up with here. This is the erroneous code repo.
I got an error saying:
Failed to load resource: the server responded with a status of 500(Internal Server Error)`
and for such a code snippet, it always redirected to the failure URL (/routes/auth.js):
.get(passport.authenticate('twitter',
{
successRedirect: '/users/',
failureRedirect: '/error/'
})
);
Based on the current commit, I can successfully get the token from Twitter API. The callback URL is as such:
http://localhost:3000/auth/twitter/callback?oauth_token=(token)&oauth_verifier=(token)
Questions:
What went wrong?
If trying to debug the error, how could I construct the error-first callback (I did NOT even know where and how to output debug logs)?

204 error code then 500 error code responses

So I have an application which needs to send data to the API which is created by our team leader using NodeJS with Express.js.
On my end I have laravel application which using VueJS for the UI. Inside the Vue JS component. I am using axios to request to the API.
axios.post('https://clearkey-api.mybluemix.net/sendcampaign', request)
.then(function(response) {
//console.log(response);
})
However, it returns 204 which means according to this https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
204 No Content
The server has fulfilled the request but does not need to return an
entity-body, and might want to return updated metainformation. The
response MAY include new or updated metainformation in the form of
entity-headers, which if present SHOULD be associated with the
requested variant.
If the client is a user agent, it SHOULD NOT change its document view
from that which caused the request to be sent. This response is
primarily intended to allow input for actions to take place without
causing a change to the user agent's active document view, although
any new or updated metainformation SHOULD be applied to the document
currently in the user agent's active view.
The 204 response MUST NOT include a message-body, and thus is always
terminated by the first empty line after the header fields.
Then next it returns 500 Internal Server Error. So in my opinion it returns this error because there is no content to be returned from the server?
Can you tell me other possible problems why it return that response?
Check if the "HTTP method" of the 204 is OPTIONS and if the method of the 500 is POST.
If both are like that, then you are seeing first a CORS pre-flight request (the OPTIONS that returns 204) and then the actual request (the POST that returns 500).
The CORS pre-flight request is a special HTTP message your browser sends to the server when the webpage and the backend are hosted at different addresses. For example, if your website is hosted at http://localhost but the backend you are trying to access is hosted at https://clearkey-api.mybluemix.net.
The reason of the 204 just means your backend endpoint is correctly setup to handle requests for /sendcampaign (you can ignore it). The reason of the 500 is because of some exception in the implementation of the function that handles that endpoint.

Setting Error Pages for a specific path

I am using ECS for a webapp, and i setup an Error Pages definitions for codes 404 and 502. My current setup returns a static maintenance.html file (hosted on S3) and returns a code of 200. I have to return 200, otherwise Outlook (which hosts my app) will not render the returned html, and show an ugly error page instead.
The problem I'm having with it, is that a later API call from my clientside app to my server, might also return 404. With the current setup, CloudFront intercepts this reply, and returns the maintenance.html with code 200. So now my app doesn't know anything is wrong, and later fails on parsing the reply.
Is there a way to define the Error Pages to only handle specific requests? For my usage, I'd like them to only handle calls to my /static/index.html files. If some other file/API call is actually missing from the server, I'd like my client to get the 404, so it can handle it properly.
So to answer your question according to the documentation I read there is currently no way to do this from cloudfront Error Pages Config.
However, We had a similar problem, but in our case API calls were returning a 500 Error with a s3 custom error html instead of the actual server error that I expected only for API calls.
What we ended up doing in this case was a handler in the back end for 500 errors that would return a response code that we were not using in the cloudfront Error Pages if the request Url had the pattern of API calls (we used http Error Code 406) and then the handler will reply with the 406 response code and the whole error instead of the 500 with the s3 response html only when failed over the api url pattern. I know this does not solve the problem the way you would have like to, but probably you may find it helpful until cloudfront allows a custom error response based in a Path Pattern.

Resources