Skip to content

Conversation

@sohankshirsagar
Copy link
Contributor

@sohankshirsagar sohankshirsagar commented Jan 17, 2026

  • add simple filtering on status codes in CLI when replaying local traces (status code >= 300)

Note

Adds new HTTP client coverage and replay robustness while aligning error/content-type rules.

  • New instrumentation: Implement urllib.request client instrumentation (record/replay, body caching, transforms, mock fallback) with comprehensive e2e test app, Docker setup, and runner
  • PyJWT (REPLAY mode): Patch verification (_merge_options, _verify_signature, _validate_claims) to bypass during replay; auto-register in SDK
  • SDK init: Auto-initialize urllib.request instrumentation; README lists PyJWT and urllib.request support; type-check overrides for pyjwt
  • Error semantics: Change server error threshold from >=300 to >=400 in Django, FastAPI, and WSGI; trace blocking updated accordingly
  • Content type policy: Accept HTML (added to acceptable decoded types)
  • Mocking/telemetry: Richer debug logs when mocks not found; urllib3 mock responses now include finalUrl/geturl in outputs

Written by Cursor Bugbot for commit 39b4bef. This will update automatically on new commits. Configure here.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 20 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="drift/core/content_type_utils.py">

<violation number="1" location="drift/core/content_type_utils.py:116">
P3: The comment above ACCEPTABLE_DECODED_TYPES is now inaccurate because HTML was added to the allowed set. Update the comment to reflect that HTML is also acceptable.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

When urllib raises HTTPError for 4xx/5xx responses, the instrumentation
now correctly replays this by raising HTTPError instead of returning a
normal MockHTTPResponse. This ensures application code catching HTTPError
behaves the same in RECORD and REPLAY modes.

- Add _raise_http_error_from_mock method to reconstruct HTTPError
- Check for errorName in _try_get_mock and raise appropriately
- Re-raise HTTPError/URLError exceptions to propagate correctly
When urllib follows redirects, response.geturl() should return the final
URL after all redirects. The instrumentation now:

- Captures finalUrl in RECORD mode when it differs from request URL
- Uses finalUrl in REPLAY mode so MockHTTPResponse.geturl() returns
  the correct final URL instead of the original request URL

This ensures application code that checks the final URL after redirects
behaves the same in RECORD and REPLAY modes.
Extract shared logic into helper methods:
- _build_input_value(): constructs HTTP request input value dict
- _build_input_schema_merges(): creates schema merge hints for headers/body

Both RECORD (_finalize_span) and REPLAY (_try_get_mock) modes now use
these helpers, eliminating ~60 lines of duplicate code and ensuring
consistent behavior between modes.
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 3 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="drift/instrumentation/urllib/instrumentation.py">

<violation number="1" location="drift/instrumentation/urllib/instrumentation.py:783">
P2: Recorded URLError exceptions are not re-raised during replay. The new error handling only raises HTTPError, so URLError recordings fall through to a 200 OK mock response, hiding failures and changing application behavior. Handle URLError (and other urllib errors) similarly to HTTPError so replay matches record behavior.</violation>
</file>

<file name="drift/instrumentation/urllib/e2e-tests/src/test_requests.py">

<violation number="1" location="drift/instrumentation/urllib/e2e-tests/src/test_requests.py:102">
P2: The "HEAD request" test uses GET, so it won’t exercise HEAD-specific behavior. Use the HEAD method to match the test intent.</violation>

<violation number="2" location="drift/instrumentation/urllib/e2e-tests/src/test_requests.py:105">
P2: The "OPTIONS request" test uses GET, so it won’t exercise OPTIONS-specific behavior. Use the OPTIONS method to match the test intent.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Copy link
Contributor

@jy-tan jy-tan left a comment

Choose a reason for hiding this comment

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

Remember to update README

@sohankshirsagar sohankshirsagar merged commit ba09fa6 into main Jan 19, 2026
20 checks passed
@sohankshirsagar sohankshirsagar deleted the sohan/pyjwt-instrumentation branch January 19, 2026 19:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants