How to set http headers for multiple messages in nodered? - javascript

I am developing a flow that aims to divide a huge message into smaller messages. I have achieved all the logical part for dividing the msg, however, when sending all those small messages to a http response node I get the following error:
"Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client".
Of couse, I specified the headers in the http response node, but without any success so far.
It's important to mention that I get this error after the 1st small message is sent, so yeah, basically the following messages trigger this error.
Any idea how to resolve this error ?
Things that I've tried so far:
Specify the headers in the http response.
Put a function before the response node and specify the headers of the msg in the function itself.

you can add a Catch node to catch the Exception Errors from the HTTP Response Node. In addition to the Catch node, you can configure a Switch node to Filter out the HTTP_HEADERS_SENT messages to debug other Exception Errors.

The Node-RED HTTP-Response node does not support HTTP Chunked encoding. This means that the entire response needs to be held in the msg.payload field of a single input message. That message needs to also originate from a HTTP-In node (it carries the object needed to send the response back).
This also means that Headers need to either be set in the msg.headers field of the same object or in the config of the HTTP-Response object.

Related

What HTTP code i shuld return if nothing added to db in post method?

I have a post method that add an object to db. But what I should return if nothing added? I need to handle it in ajax request.
Depending on what is your use case you can:
The new object violates conditions - either it already exists (unique constraint) or some other validations
-> Then return 422 Unprocessable Entity alongside with some error message in the body.
You are doing server side deduplication - you want to gracefully send new objects and not care about duplications on client side
-> Either pretend everything is OK, ie 201 Created and return the original existing object as response. Or distinct between the states with 201 Created for newly recorded object and 303 See other with the original record as URL or just 204 No content
There is unexpected error on the server side during saving something that was expected to be recorded
-> 500 Server Error
A status 500 (server error) would make most sense to me.
200 success
300 rediret
400 client error (me)
500 server error (you)
You didn't add the object I posted to you, into the db, so you return 500. That way I can catch the error.
Edited to explain the status codes a bit better:
Don't return 200 unless there was a success with the post. You never wanna return 200 with message "didn't work"
If I'm sending you a wrong object/information to save you should send 400
If the connection on your end is lost or there's a problem with the insert statement a 500 would probably suit best.
And further: You can always send detailed messages with your status codes. But depending on the users using this service be careful not to expose/send information like sql errors.
If the reason is bad data from the client in some form, you should use a status in the 400-range, most likely 422.
If the reason is due to some error on the backend you should use one in the 500-range. There are many different status codes to use. You should read up on them and use the one(s) that apply to your scenario.
This is a good resource on HTTP statuses.
you should use 204 status code (204 ==> No Content)

AJAX response failure

When we make any AJAX request, what are the different possibilities for the response failing and how do we verify it on client-side?
Is it purely based on "response.status"
I am using DOJO and see one place where I am getting response from the server, but response.status is "undefined" (dojo.xhrPost response)
More importantly technically speaking from the backend/server-side, do we have to explicitly do/pass something to indicate response failure on the client-side OR is that automatically handled (assume Java in the backend)?
The whole HTTP state is based on the status of the HTTP call. The server side component should be able to send the right failure response code/HTTP Status 4xx/5xx as expected. This is irrespective of the type of server/client side component.
However, not all the failure cases needs to throw 5xx or 4xx status. For example, you may try to add a new record, if record already exists, the server can still send 200 OK response and give message stating - Record already available.
It's all with the webdeveloper's discretion :)
Have you checked the network tab of your developer tools to find the request matching the XHR that failed? It could probably tell you more.
If the status is undefined, I would guess that perhaps the XHR was aborted entirely or that there was an error even connecting, or resolving DNS, etc.

Which Http error/status code is the appropriate?

I've carefully read all HTTP error/status codes, still not clear which is the appropriate to return in the following scenario:
The request is an Ajax request, so the handling of the error situation depends on the client javascript code, preferably it will give a notification.
At server side an unexpected error occurs (say DB operation fails), however the exception is handled server side, and appropriate error message (as string) is created there.
The 'unexpected error' implies HTTP 500, however I would like to differentiate between real server internal (and unhandled) errors and handled use cases what I've described above.
Which Http error/status code is the appropriate?
Does it matter if the request a query (using GET) or some update (using POST)?
Both scenarios that you described are server errors. Regardless if it was a DB operation that fails or you server-side code didn't handle an error (unhandled error). Therefore, for the Front-end point of view, A server error has occurred (500 error status).
Now, differentiating an custom application error from an unhandled error, comes down to which server-side technology you are using. You can decorate (add a property) your error object with some information that only your handled application errors would have. Therefore, on the Front-end, if that property is present, it's a known server error.
//500 error - unknown model
{ status: 500, exception: "my unknown error." }
//500 error - known model
{ status: 500, exception: "DB script has failed.", errorCode: 001 }
It shouldn't matter if the call is a GET or a POST. Both Methods could return the same http status code.
The appropriate response is 5xx Server Error. Depending on the type of error you may choose to use "503 Service Unavailable" or "501 Not Implemented", but in the more generic cases opt for "500 Internal Server Error" (GET or POST doesn't matter).
You may choose to provide a custom response body to differentiate between handled error messages and unhandled ones.
There is a list of available status codes. Usually if the request was valid, you'll receive the status code 200. If a resource could not be found, you'll get 404. All the server side errors will result in a 500. If you intend to differentiate between your server side errors, you'll have to catch them manually and return a response with a different status code. Note: Status code 500 is the worst of them all. You should not use it, for example, to return the error messages in case a validation has failed. Use a different status code in this case.

How to handle CORS error code?

Edit: I just realized this is a duplicate of Recommended solution for AJAX, CORS, Chrome & HTTP error codes (401,403,404,500), and he tried the idea I propose at the end. But I can't tell if he succeeded (dud user?), and no one else has posted a solution or even a comment, so I think it's worth fishing for new answers.
Problem:
I send a properly-executed (edit: IMproperly-executed. End of story...) CORS request.
The server receives the request and attempts to process it.
The server returns an error response, for example a 422 Unprocessable Entity, along with JSON information about the errors. The idea is that my app could receive this error information and handle it appropriately in the UI.
The browser blocks my error handler from getting the response content, or even getting the status code.
Showing that the browser received the 401 status code but treated it as a CORS security error:
The response object, showing that my code cannot access the response data (data: "", status: 0):
How have other people handled this limitation? My best guess right now is to hijack an HTTP "success" code (2XX) as an error code, and then include the error information in the response. This prevents me from using the ajax error handlers in a normal way, but I'm handling this as a global ajax filter anyway, so this filter would capture the deviant success code and trigger the error handlers instead.
The console message indicates that the server isn't sending the required Access-Control-Allow-Origin header when it sends the 401 response code.
You won't be able to use the CORS error handler to inject content into the DOM unless you fix that.
The server is likely sending the header correctly on responses with a 200 response code. It needs to do it for other response codes, though, if you wish to use data from those response codes.
Fix that on the server end before making design compromises on the client side. That may solve your problem straight away.
It seems it's an opaque response where you can't obtain the headers or the response. And everything is set to null or empty.
https://developer.mozilla.org/en-US/docs/Web/API/Response/type
Or maybe in the server you should add:
Access-Control-Allow-Origin: *
Very late answer but in case someone wants to check whether an error occurred while sending an XMLHttpRequest and then take appropriate actions (on the CLIENT side), then this is a quick workaround:
try{
request.send();
}catch(err){
if(e.toString().startsWith("NetworkError")){
//pasre the string to check error code
//and take appropriate actions
}
}
This is needed because the onreadystatechange function doesn't get executed when a NetworkError occurs and, in fact, the whole script is terminated.

How to set boolean value true/false in to backbone model attribute

I am trying to set boolean value to the model attribute as follows :
investAdjustCollection.models[i].set({isUploaded:false});
this creates problem when i send request to server to take some action on the modes data but i get the following exception at the client level
Uncaught SyntaxError: Unexpected token <
and at the server level i get
POST http://localhost:8080/api/trade/createinvestadjust 400 (Bad Request)
if i remove investAdjustCollection.models[i].set({isUploaded:false}); than the server call is made without any issue.
so how to set boolean value true/false in to a bakcbone model.
First guess is for unknown reasons (validation failed? bug in the server code?), when you send that data, the server throws an exception and instead of responding with a valid JSON response, the response body is an HTML error page with an error message, so when Backbone tries to parse that as JSON, it's invalid. Check your server side logs. Even though they are saying Bad Request, I suspect an exception in the server. However, just to be sure, use the developer tools to examine the headers and body of your PUT request from the browser and make sure the Content-Type is correct and the request body is valid JSON.

Categories