I have a handler that is more or less this:
async def handler(request):
response = web.StreamResponse(headers={
'Content-Type': 'text/plain; charset=utf-8',
'Connection': 'keep-alive',
})
response.enable_chunked_encoding()
await stream_response.prepare(request)
try:
await do_a_thing(response) # writes into response
except Exception as e:
# log the exception. I sometimes catch a CancelledError here
await response.write_eof()
return response
When nothing goes wrong, the page is generated fine.
When a CancelledError occurs in do_a_thing(), the browser shows an error page ERR_INCOMPLETE_CHUNKED_ENCODING, even though:
the CancelledError is definitely NOT happening on writing the response (it's during an HTTP GET to another URL in do_a_thing())
I catch the exception
I don't do anything different to write the EOF and return the response
I must be doing something wrong, or not doing something right, but I can't tell what.
Can anyone see what it might be?
Related
Using aiohttp, if you set raise_for_status=True, it will raise a ClientError exception.
Is it possible to access the server's response in that ClientError exception?
For instance, a server could return a 4xx error, with a JSON response explaining why, and it would be interesting to access it to manage the error (such as Stripe's API).
try:
async with aiohttp.ClientSession() as session:
response = await session.get('http://127.0.0.1:5000/auth/user', raise_for_status=True)
except aiohttp.ClientError as e:
print(e.response.content) # ?
Is it possible to access the server's response from the exception part?
If you don't want to set raise_for_status=False (although I don't understand why you wouldn't) you can catch the exception and grab the response json like so:
try:
async with aiohttp.ClientSession() as session:
response = await session.get('http://127.0.0.1:5000/auth/user', raise_for_status=True)
except aiohttp.ClientError as e:
json = await response.json()
# do something with json
# maybe you want to raise your own exception
# if not, just re-raise e
raise e
I have a server in Go that handles the files upload. It is a legacy code so I can't touch it so much.
The server should interrupt the upload if it detects some errors in the request header and it should return a message to the client that something is gone wrong.
The handler function is something like the following:
func(w http.ResponseWriter, r *http.Request) {
// Check the header. Could be more than one.
if r.Header.Get("key") == "not as expected" {
w.WriteHeader(500)
w.Write("key is wrong")
return
}
//handle the file upload
}
The header check is only an example to show the problem
The server closes the connection after Write and return from the function even if the request is not completed (file received).
On the client-side (Java) when I make a request with the key with a wrong value and the file to upload as a body, I get a broken pipe exception and It can't handle the response correctly.
Actually I can't touch the client-side code.
There is way on server side to wait until the request ends before closing the connection?
The "broken pipe" error¹ seen on the Java client suggests the client insists on sending the payload (body) of its request before attempting to read the response from the server.
In HTTP/1.1 (and 1.0), the client is correct: nothing in the spec says the client has to expect the server to respond before the whole request — that is, the header and the body, if any, — gets submitted.
In your particular case, the simplest approach is to pipe the clien's body to nowhere and after that respond with an error. One idiomatic approach is using io/ioutil.Discard type:
func(w http.ResponseWriter, r *http.Request) {
// Check the checksum header
if r.Header.Get("key") == "not as expected" {
_, err := io.Copy(ioutil.Discard, r.Body)
if err != nil {
// The client went away.
// May be log something, then bail out.
panic(http.ErrAbortHandler)
}
w.WriteHeader(500)
w.Write("key is wrong")
return
}
//handle the file upload
}
net/http.ErrAbortHandler may be used to tell the HTTP server library code the request should not be carried out the normal way.
By the way, responding with 5xx to an ill-formed client request is incorrect, you should have been using 4xx instead. But it's a legacy code, so just take this as a hint for future developments.
¹ See EPIPE in the send(2) manual page.
I am trying to post data in my database but every time I do try to dod it I get a 405 error. Also python has an error saying that I am submitting an empty list. Please point me in the right direction to solve this problem.
const axios = require('axios')
let URL = 'http://127.0.0.1:5000/Walls/saveComments'
let HEADERS = { 'Content-Type': 'application/json' }
let data = {
'post': post,
'time': time
}
axios.post(URL,data, HEADERS)
.then(function (response) {
console.log(response);
})
// Axios Call to Save A Post in Backend
The HTTP 405 error means that the server does not allow the HTTP request method that the client sent.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
The HTTP method you're using in the code example you shared is POST. Therefore, it seems that your server does not accept POST requests.
In order to fix this, either change the request method to something that is supported, or change the server to allow POST requests.
I am developing a website [using React for front-end // Spring for backend] and in this website there is an admin panel. There is a button which lets other admins to add users to the database but I have a problem with axios' post method.
I checked so many different sources but couldnt find exactly what I am looking for. So here I am.
I get this error, 401 error code, unauthorized client, when using this syntax below
async addUsers(newData){
const headers = {
'Content-Type': 'application/json',
'Authorization': window.$auth
}
await Axios.post(
"http://localhost:8080/admin/addUser",
JSON.stringify(newData),
{headers: headers}
);
}
Before, I tried using a different syntax which I think is wrong, and with this syntax I get 415 error code: 415 error code, unsupported media type
async addUsers(newData){
await Axios.post(
"http://localhost:8080/admin/addUser",
JSON.stringify(newData),
{auth:window.$auth},
{headers: {'Content-Type':'application/json'}}
);
}
P.S: I tried to add User manually to database using Insomnia REST client and it successfully adds it and returns 200 Code.
Could someone help me with this problem, please?
Instead of sending authorization token with each request better add it as a default header. First check if token exist if it is exist add it
if(authorization_token){
axios.defaults.headers.common['Authorization'] = authorization_token;
}
It looks like this "authorization always returning 401 error code" was a known issue. Changing the complete syntax fixed it. Here is the site that I found the solution on https://github.com/axios/axios/issues/926
Here is the part of my code which that I fixed and now works:
async addUsers(newData){
await Axios({
method:'post',
url:'http://localhost:8080/admin/addUser',
data:JSON.stringify(newData),
auth:window.$auth,
headers:{'Content-Type':'application/json'}
})
}
I use $http to retrieve data from server. In case error happen, all statusCode = -1. I cannot get correct errorCode to handle in client. I don't have permission to update server code.
$http(options).then(function (response) {
if (response.status === 200) {
resolve(response.data);
} else {
exceptionHandler(response);
}
}, function (error) {
exceptionHandler(error);
});
console.log is put on exceptionHandler function.
Please help me get correct error code. Many thanks.
In the responses you have shown, the 404 error is available as error.status but the other two responses were denied access by your browser when it performed the preflight OPTIONS request.
In that case the browser returns a status of -1 to indicate that the request was aborted. There is no HTTP status code for your request because it was never sent. The status 500 shown in the console log is not made available to any javascript code.
You should handle a status of -1 as indicating that no response was received from the server, either because it was never sent (this case), or because it was sent but timed out.