-
-
Notifications
You must be signed in to change notification settings - Fork 535
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
Uses explicit null as 204 response body when handling the "response" worker event #570
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 4d596ee:
|
eebd900
to
c9548db
Compare
@@ -25,7 +25,8 @@ export function createResponseListener(context: SetupWorkerInternalContext) { | |||
return | |||
} | |||
|
|||
const response = new Response(responseJson.body, responseJson) | |||
const responseBody = responseJson.status === 204 ? null : responseJson.body |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found https://fetch.spec.whatwg.org/#statuses => IMHO let's check all null body statuses here:
const responseBody = responseJson.status === 204 ? null : responseJson.body | |
const responseBody = [101, 204, 205, 304].includes(responseJson.status) ? null : responseJson.body |
if this is hot-path for perf optimization, maybe a new Set(...)
in some util file can be used 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great suggestion, but also a great example of why reflecting a spec this way is a huge redundancy. I wish to find a different way to retrieve a 204 response body as null
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, no ideas about the clean way yet :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well.. I do have an idea - responseJson.body === '' ? null : responseJson.body
- but totally not sure how that would break all edge cases with empty body in 200
and other responses 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the responses that have an empty string body? There must be a differentiation between them as those responses that have no body (null
). With the logic above, both cases will result in res.body
being null
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, this distinction between null and empty string is really strange, no idea what was the reason to make it different in the spec :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I use this suggested change as a stop-gap for now? I'm using only msw
for local development and it'd be nice to not have that warning in console (I'm using patch-package
for these purposes).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@comatory, I'd rather recommend you edit the mockServiceWorker.js
with a similar change instead. Changing what lies in node_modules
isn't a reliable way to fix anything, as the modules will be pruned once you re-install the dependencies.
If you're using some tool to ensure the persistent change in a node module across installs, then you can add this suggestion into msw
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kettanaito I see. However with patch-package the changes are re-applied after installation so it's safe (and actually recommended way) to do it. I'm fine with this solution, once this problem is fixed, I'll just remove the patch from my codebase.
After looking into the ways to differentiate between an empty string response and a null response, I've tried to read the function readStream(stream) {
return new Promise((resolve, reject) => {
let result = null
if (stream.locked) {
return resolve(result)
}
const reader = stream.getReader()
reader
.read()
.then(function processText({ value, done }) {
if (done) {
reader.releaseLock()
return resolve(result)
}
const resolvedValue =
typeof value === 'string'
? value
: new TextDecoder('utf-8').decode(value)
result = (result || '') + resolvedValue
reader.read().then(processText)
})
.catch(reject)
})
} And then reading the stream: const responseBody = await readStream(clonedResponse.body) While working with We can fallback to new Response(responseJson.body || null, responseJson) By doing so:
|
c9548db
to
4d596ee
Compare
I've settled on the const res = new Response(null, { status: 204 })
res.body // null, as expected |
@Aprillion, @marcosvega91, may I please ask for your review on this? GitHub's "re-request review" is broken for me. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your observation is right, I think is great 💪 Great!!
I just checked |
@@ -25,7 +25,7 @@ export function createResponseListener(context: SetupWorkerInternalContext) { | |||
return | |||
} | |||
|
|||
const response = new Response(responseJson.body, responseJson) | |||
const response = new Response(responseJson.body || null, responseJson) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is rather brave, but when handling a Response
instance there is no difference between working with a new Response(null)
and new Response('')
in terms of the operable response body (i.e. .json
/.text
/etc.).
Motivation
When handling a 204 status (actual) response, it's expected for it to have no body. However, there is no way to check if a response has no body given an arbitrary potentially 204 response:
Looks like we need a safe-guard on our side to prevent the construction of a
Response
instance with an empty string body in case of a 204 status response:Changes
null
in case the response status is204
, regardless of what its actual body is (in that case it's alwaysnull
).