Skip to content
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

refactor(fetch): revert to original code in endSpanOnSuccess #3037

Merged
merged 1 commit into from
Jul 30, 2022

Conversation

Ugzuzg
Copy link
Contributor

@Ugzuzg Ugzuzg commented Jun 13, 2022

Which problem is this PR solving?

This spanResponse object is not used for anything, and I can't figure out its purpose:

const spanResponse = {
status: response.status,
statusText: response.statusText,
headers: response.headers,
url
};
if (response.status >= 200 && response.status < 400) {
if (response.url != null && response.url !== '') {
spanResponse.url = url;
}
}

The override doesn't make sense, as it sets the same value already present in the initialised object:

if (response.status >= 200 && response.status < 400) {
if (response.url != null && response.url !== '') {
spanResponse.url = url;
}
}

I have amended the code to what I think makes sense and was the original intention. Opening a PR to have a discussion.

Short description of the changes

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Checklist:

  • Followed the style guidelines of this project
  • Unit tests have been added
  • Documentation has been updated

@Ugzuzg Ugzuzg requested a review from a team June 13, 2022 16:24
);
assert.strictEqual(
attributes[keys[2]],
redirectedUrl,
Copy link
Contributor Author

@Ugzuzg Ugzuzg Jun 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense that the http.url attribute's value is the url before the redirection, but http.host is the host after the redirection? Feels strange.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, you're right, it does indeed feel strange. As far as I can tell, it also does not follow the spec. There it states that:

Retries and redirects cause more than one physical HTTP request to be sent. A CLIENT span SHOULD be created for each one of these physical requests. No span is created corresponding to the "logical" (encompassing) request.

It looks like to me that we'd need to instrument fetch in a way that it creates spans on each redirect (in that case host.host and http.url should be the same). However, I have to admit that I do not know enough about the internals of fetch right now to come up with a way to implement that. We should create an issue to track this, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the discrepancy is introduced by this change, a better fix for now should be to just remove spanResponse variable, and then implement proper redirection spans.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. If there's a way to create proper redirection spans we should do it 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't look like it is possible, sadly.
Redirects are not exposed to APIs: https://fetch.spec.whatwg.org/#atomic-http-redirect-handling
There's a manual redirect mode, but it can't be used in any useful way.

"manual"
Retrieves an opaque-redirect filtered response when a request is met with a redirect, to allow a service worker to replay the redirect offline. The response is otherwise indistinguishable from a network error, to not violate atomic HTTP redirect handling.

An opaque-redirect filtered response is a filtered response whose type is "opaqueredirect", status is 0, status message is the empty byte sequence, header list is empty, and body is null.

@Ugzuzg Ugzuzg force-pushed the fix/fetch-span-response branch from c653bd4 to bd01667 Compare June 13, 2022 16:29
@codecov
Copy link

codecov bot commented Jun 13, 2022

Codecov Report

Merging #3037 (e9d7830) into main (492a3e8) will increase coverage by 0.01%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main    #3037      +/-   ##
==========================================
+ Coverage   93.09%   93.10%   +0.01%     
==========================================
  Files         195      195              
  Lines        6386     6384       -2     
  Branches     1349     1348       -1     
==========================================
- Hits         5945     5944       -1     
+ Misses        441      440       -1     
Impacted Files Coverage Δ
...s/opentelemetry-instrumentation-fetch/src/fetch.ts 97.02% <100.00%> (+0.55%) ⬆️

@Ugzuzg Ugzuzg force-pushed the fix/fetch-span-response branch 2 times, most recently from 63a498f to f9ee378 Compare June 13, 2022 16:32
@dyladan
Copy link
Member

dyladan commented Jun 17, 2022

@pichlermarc looks like you originally introduced this object in #2871 please look at this

@pichlermarc
Copy link
Member

@Ugzuzg you're right, it does not make sense. I committed this by mistake in #2871. 😞 The code here is actually supposed to be the original code:

        function endSpanOnSuccess(span: api.Span, response: Response) {
          plugin._applyAttributesAfterFetch(span, options, response);
          if (response.status >= 200 && response.status < 400) {
            plugin._endSpan(span, spanData, response);
          } else {
            plugin._endSpan(span, spanData, {
              status: response.status,
              statusText: response.statusText,
              url,
            });
          }
        }

Back then, I must have been trying to figure out what caused the url to be null, but that was actually caused by #2884. After I figured out that this was the issue, I made the change to use a local implementation of parseUrl() and must have accidentally added these changes too.

I can create a fix, or you can do it with this PR.
Sorry about that and thanks for bringing this up! 😥

@Ugzuzg
Copy link
Contributor Author

Ugzuzg commented Jun 20, 2022

@pichlermarc, the current change in the pull request behaves in the same way you're describing (with the addition of response.url check). Do you still want me to change it? Or can we keep it as is?

@Ugzuzg Ugzuzg force-pushed the fix/fetch-span-response branch from f9ee378 to a635275 Compare June 20, 2022 12:29
@pichlermarc
Copy link
Member

@Ugzuzg As it behaves the same I think we can keep this as is, thanks for working on this! 🙂
You'll just need a changelog entry and then we can get this PR going. 🙂

@Ugzuzg Ugzuzg force-pushed the fix/fetch-span-response branch from a635275 to 077d9fa Compare June 20, 2022 13:40
CHANGELOG.md Outdated Show resolved Hide resolved
);
assert.strictEqual(
attributes[keys[2]],
redirectedUrl,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, you're right, it does indeed feel strange. As far as I can tell, it also does not follow the spec. There it states that:

Retries and redirects cause more than one physical HTTP request to be sent. A CLIENT span SHOULD be created for each one of these physical requests. No span is created corresponding to the "logical" (encompassing) request.

It looks like to me that we'd need to instrument fetch in a way that it creates spans on each redirect (in that case host.host and http.url should be the same). However, I have to admit that I do not know enough about the internals of fetch right now to come up with a way to implement that. We should create an issue to track this, though.

@Ugzuzg Ugzuzg force-pushed the fix/fetch-span-response branch from 077d9fa to 229d902 Compare June 20, 2022 18:42
Copy link
Member

@pichlermarc pichlermarc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! 🙂 Thanks for bringing this up and taking the time to fix it! 🙂

Copy link
Member

@dyladan dyladan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of my comments have the same theme. The impl looks fine but the tests you added are very hard to read because of the indirect way you are accessing attribute values.

@legendecas
Copy link
Member

Nonblocking: an update to the PR title will be most helpful.

@Ugzuzg Ugzuzg changed the title fix(fetch): pass spanResponse to _endSpan fix(fetch): remove unused spanResponse variable Jul 22, 2022
@Ugzuzg Ugzuzg force-pushed the fix/fetch-span-response branch 3 times, most recently from 47ab8c2 to de5270b Compare July 29, 2022 19:16
@dyladan
Copy link
Member

dyladan commented Jul 29, 2022

Not really a fix. I would retitle to refactor

@Ugzuzg Ugzuzg force-pushed the fix/fetch-span-response branch from de5270b to e9d7830 Compare July 29, 2022 19:28
@dyladan
Copy link
Member

dyladan commented Jul 29, 2022

Not really a fix. I would retitle to refactor

I meant the PR title not so much the commit 😄

@Ugzuzg Ugzuzg changed the title fix(fetch): remove unused spanResponse variable refactor(fetch): revert to original code in endSpanOnSuccess Jul 29, 2022
@vmarchaud vmarchaud merged commit fc4dcba into open-telemetry:main Jul 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants