-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Make sure to consume HTTP error response bodies #1173
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
Changes from all commits
9ab2d4f
05eb2ba
719604f
17754cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -223,6 +223,8 @@ export class StreamableHTTPClientTransport implements Transport { | |
| }); | ||
|
|
||
| if (!response.ok) { | ||
| await response.body?.cancel(); | ||
|
|
||
| if (response.status === 401 && this._authProvider) { | ||
| // Need to authenticate | ||
| return await this._authThenStart(); | ||
|
|
@@ -463,6 +465,8 @@ export class StreamableHTTPClientTransport implements Transport { | |
| } | ||
|
|
||
| if (!response.ok) { | ||
| const text = await response.text().catch(() => null); | ||
|
|
||
| if (response.status === 401 && this._authProvider) { | ||
| // Prevent infinite recursion when server returns 401 after successful auth | ||
| if (this._hasCompletedAuthFlow) { | ||
|
|
@@ -525,7 +529,6 @@ export class StreamableHTTPClientTransport implements Transport { | |
| } | ||
| } | ||
|
|
||
| const text = await response.text().catch(() => null); | ||
| throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`); | ||
| } | ||
|
|
||
|
|
@@ -535,6 +538,7 @@ export class StreamableHTTPClientTransport implements Transport { | |
|
|
||
| // If the response is 202 Accepted, there's no body to process | ||
| if (response.status === 202) { | ||
| await response.body?.cancel(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. awesome. This line I have been meaning to add for ages |
||
| // if the accepted notification is initialized, we start the SSE stream | ||
| // if it's supported by the server | ||
| if (isInitializedNotification(message)) { | ||
|
|
@@ -609,6 +613,7 @@ export class StreamableHTTPClientTransport implements Transport { | |
| }; | ||
|
|
||
| const response = await (this._fetch ?? fetch)(this._url, init); | ||
| await response.body?.cancel(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. feels weird cancelling the body before checking if response is okay. I'm not super clued up on this I just want to check line 620 will still work as expected.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. I think both Tried it out with this script: (async () => {
// Fetch something that returns a body
const response = await fetch('https://httpbin.org/json');
console.log('Before cancel:');
console.log(' status:', response.status);
console.log(' ok:', response.ok);
console.log(' headers.content-type:', response.headers.get('content-type'));
// Cancel the body stream
await response.body?.cancel();
console.log('\nBody cancelled.\n');
console.log('After cancel:');
console.log(' status:', response.status);
console.log(' ok:', response.ok);
console.log(' headers.content-type:', response.headers.get('content-type'));
// Try to read the body now - this should fail
console.log('\nTrying to read body after cancel:');
try {
const text = await response.text();
console.log(' text:', text.substring(0, 50));
} catch (e) {
console.log(' ERROR:', e.message);
}
})();Which gave the following output: So this looks good to me. We could put 2 cancels, one inside the 405 check and then one at the end of the function, but this seems fine. |
||
|
|
||
| // We specifically handle 405 as a valid response according to the spec, | ||
| // meaning the server does not support explicit session termination | ||
|
|
||
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.
great