-
-
Notifications
You must be signed in to change notification settings - Fork 935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Got throws an HTTPError for 304 responses #251
Comments
@lukechilds |
304 isn't a redirect, it means the content hasn't been modified. I'm doing a GET request with a date set in the if-modified-since header. The API is returning a 304 meaning the resource hasn't changed since the copy in my cache but this causes 2 secs, just putting some code together. |
@lukechilds yup, you right – 304 case will be treated as error. But error does contains headers under
So you can check for Maybe it is better to make this case valid and not throw error thou (if you do not care about redirects, you can achieve this by disabling |
const got = require('got')
// Make API request
got('https://onionoo.torproject.org/summary?limit=1')
.then(res => {
// Log response info (should be 200)
console.log(res.statusCode, res.headers)
// Make another request with if-modified-since set
// This should give us a 304
return got('https://onionoo.torproject.org/summary?limit=1', {
headers: {
'if-modified-since': res.headers['last-modified']
}
})
})
// This should run, but got throws an error
.then(res => console.log(res.statusCode, res.headers))
// You can see we got a successful 304 response
.catch(console.log) |
Oops, just seen your reply. The headers aren't in the error object, that's my problem. You can see in the output from the above code:
|
@lukechilds .catch((err) => console.log(err.response)) |
Ahhh, thank you, I didn't realise that. Well that gives me a way to resolve this on my end. It definitely seems odd to me that it throws on a 304 though. Just had a look and it appears to be reading the body stream that's causing the error. Although the console log says it's an Could this be caused by the 304 having no body? |
@lukechilds it should point on line |
Oops, yep just realised that. |
Would you accept a PR to "whitelist" 304 in the status code check? |
@lukechilds maybe, I'm still thinking about it. @sindresorhus what do you think? Also this will be a major change and could be published only in |
Ok, it's only a simple change, just submitted a PR. Take it or leave it |
The 304 code should be treated differently because it usually does not contain the response content. |
@julien-f when you say treated differently do you mean treated differently as in not having an error thrown or treated differently as in I need to do something else in my PR? |
@lukechilds It's just my opinion, but if got does not behave differently (rejects) in case of 304, it force users to handle this case or they will find themselves without any content. I know that it should only happen when the correct headers are set but still, I think it's much more obvious to debug when an error is thrown. |
@julien-f Ah I see, that's a valid point. However, I still think it shouldn't throw an error because, like you said, a 304 should only be returned if someone's asking whether their cached version is still good, so they'll be expecting to handle it. |
I hit this recently too, in an aysnc/await context having to do a try/catch on a valid response is a bit awkward. This is a bit of a contrived example but... async function updateContent(lastModified) {
const { body } = await got('https://example.com/status', {
headers: { 'if-modified-since': lastModified }
})
if (body) {
await doSomething(body)
}
}
// vs
async function updateContent(lastModified) {
let response
try {
response = await got('https://example.com/status', {
headers: { 'if-modified-since': lastModified }
})
} catch (e) {
if (e.statusCode === 304) {
response = e.response
} else {
throw e
}
}
const { body } = response
if (body) {
await doSomething(body)
}
} If you're using bluebird
|
@reconbot you can't rely on |
I'm expecting no content if it's not modified. That's why I sent the extra header.
|
I don't think we should throw, but instead make it clear in the readme that the response body might be empty if you choose to send a How does |
@sindresorhus |
Seems like what we should do too. I searched the |
Good stuff, is #252 ok or do you need anything else? |
@lukechilds A test and the mentioned readme update. |
Currently implementing an API client that supports caching. It sends if-modified-since headers and will sometimes get a 304 response. If I get a 304, got throws an HTTPError. I can't catch the error and then do my stuff because the error doesn't contain the headers.
I noticed this in the readme:
Why isn't 304 allowed?
The text was updated successfully, but these errors were encountered: