Skip to content

Commit

Permalink
account for older platforms where ReadableStream can't tee()
Browse files Browse the repository at this point in the history
  • Loading branch information
MustafaHaddara committed May 22, 2024
1 parent 14c9323 commit c67e910
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
14 changes: 12 additions & 2 deletions packages/opentelemetry-sdk-trace-web/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,18 @@ export function addSpanNetworkEvents(

function _getBodyNonDestructively(body: ReadableStream) {
// can't read a ReadableStream without destroying it
// we CAN "tee" the body stream, which lets us split it, but that still locks the original stream
// so we end up needing to return one of the forks.
// on most platforms, we CAN tee the body stream, which lets us split it,
// but that still locks the original stream, so we end up needing to return one of the forks.
//
// some (older) platforms don't expose the tee method and in that scenario, we're out of luck;
// there's no way to read the stream without consuming it.
if (!body.tee) {
return {
body,
length: Promise.resolve(null),
};
}

const [bodyToReturn, bodyToConsume] = body.tee();

const lengthPromise = async () => {
Expand Down
28 changes: 28 additions & 0 deletions packages/opentelemetry-sdk-trace-web/test/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,34 @@ describe('utils', () => {
assert.strictEqual(value, jsonString);
});

it('should handle readablestream objects without a tee method', async () => {
const jsonString = JSON.stringify({
key1: 'true',
key2: 'hello world',
});
const stream = textToReadableStream(jsonString);

// remove the .tee() method to mimic older environments where this method isn't available
// @ts-expect-error
stream.tee = undefined;

const requestParams = { body: stream };
const length = await getFetchBodyLength(
'https://example.com',
requestParams
);

// we got the correct length
assert.strictEqual(length, null);

// AND the body is still readable
assert.strictEqual(requestParams.body.locked, false);

// AND the body is still correct
const { value } = await requestParams.body.getReader().read();
assert.strictEqual(value, jsonString);
});

it('should read the body of the first param when recieving a request', async () => {
const bodyContent = JSON.stringify({
key1: 'true',
Expand Down

0 comments on commit c67e910

Please sign in to comment.