Skip to content

Mock timeout scenario for default_location#163

Open
christe6-osu wants to merge 8 commits intoryansurf:mainfrom
christe6-osu:mock-def-loc-test
Open

Mock timeout scenario for default_location#163
christe6-osu wants to merge 8 commits intoryansurf:mainfrom
christe6-osu:mock-def-loc-test

Conversation

@christe6-osu
Copy link

@christe6-osu christe6-osu commented Jun 3, 2025

General:

Added a test for the timeout scenario for default_location.
Modified default_location to include a try/except block to catch Timeout exceptions.

Code:

  1. [Y] Does your submission pass tests?
  2. [Y] Have you run the linter/formatter on your code locally before submission?
  3. [N/A] Have you updated the documentation/README to reflect your changes, as applicable?
  4. [Y] Have you added an explanation of what your changes do?
  5. [N/A] Have you written new tests for your changes, as applicable?

Summary by Sourcery

Add exception handling to the default_location function to return "No data" on request timeouts or other request errors, and expand tests to simulate and verify these error scenarios.

Enhancements:

  • Wrap the API call in default_location with try/except to catch Timeout and RequestException and return "No data".

Tests:

  • Parameterize default_location tests with side_effect to mock Timeout and RequestException scenarios.
  • Add test cases for HTTP timeouts and generic request errors to ensure default_location returns "No data".

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jun 3, 2025

Reviewer's Guide

This PR enhances the default_location implementation to gracefully handle request timeouts and other request exceptions by returning “No data,” and it extends the existing test suite to mock and verify these failure scenarios.

Sequence diagram for default_location timeout handling

sequenceDiagram
    participant User
    participant default_location
    participant requests
    User->>default_location: Call default_location()
    default_location->>requests: requests.get("https://ipinfo.io/json", timeout=10)
    alt Timeout occurs
        requests-->>default_location: Raise Timeout exception
        default_location-->>User: Return "No data"
    else Other RequestException occurs
        requests-->>default_location: Raise RequestException
        default_location-->>User: Return "No data"
    else Success
        requests-->>default_location: Response (status_code)
        alt status_code == OK
            default_location-->>User: Return location data
        else status_code != OK
            default_location-->>User: Return "No data"
        end
    end
Loading

Class diagram for default_location exception handling

classDiagram
    class default_location {
        +default_location()
        +requests.get()
        +Exception handling: Timeout, RequestException
        +Returns: location data or "No data"
    }
Loading

File-Level Changes

Change Details Files
Add exception handling in default_location to return “No data” on timeouts or other request errors
  • Wrap requests.get call in try/except
  • Catch Timeout exceptions and return “No data”
  • Catch RequestException and return “No data”
src/api.py
Extend test_default_location_mocked to cover timeout and generic request-exception scenarios
  • Introduce HTTP_TIMEOUT and HTTP_REQUEST_EXCEPTION constants
  • Add side_effect parameter in pytest.mark.parametrize
  • Include test cases for Timeout and RequestException
  • Set mock_requests.side_effect to simulate exceptions
tests/test_api.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

👋 Hi! Thanks for submitting your first pull request!
• We appreciate your effort to improve this project.
• If you're enjoying your experience, please consider giving us a star ⭐
• It helps us grow and motivates us to keep improving! 🚀

Copy link
Contributor

@sourcery-ai sourcery-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.

Hey @christe6-osu - I've reviewed your changes - here's some feedback:

  • In default_location(), consider catching HTTPError (or more generally RequestException) in addition to Timeout so that non-200 responses don’t raise uncaught exceptions.
  • The test’s use of if status_code == Timeout to set a side effect is brittle; you could split the exception scenario into its own param or fixture to cleanly inject the Timeout exception.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@christe6-osu
Copy link
Author

Testing for the Timeout exception required adding code to src/api.py, which I realize may not be desirable. It is passing the pre-existing tests and the new Timeout test. However, I have not been able to get the application to work locally, so I cannot run everything to verify functionality.

Please let me know how it looks and if there is anything you would like me to change.

@christe6-osu
Copy link
Author

I see that sourcery brought up a couple issues that I had debated about but was unsure of the best approach.

Should I add another except block that catches the general RequestException as it suggests?

As for including side_effect in the parameters, I considered that but was not sure if having side_effect = None for the other tests would cause an issue. I can test this locally and push to include with the PR if it works.

@ryansurf
Copy link
Owner

ryansurf commented Jun 6, 2025

Hey @christe6-osu, I haven't had time to review this yet but wanted to let you know I've seen it! I'll get to it in the next few days

@ryansurf
Copy link
Owner

ryansurf commented Jun 11, 2025

Testing for the Timeout exception required adding code to src/api.py, which I realize may not be desirable. It is passing the pre-existing tests and the new Timeout test. However, I have not been able to get the application to work locally, so I cannot run everything to verify functionality.

Please let me know how it looks and if there is anything you would like me to change.

Hey @christe6-osu, apologies for just getting to this. I'll go ahead and test this locally myself, but what is going wrong when you are trying to run it locally?

edit: not sure what happened on your end, but i made a small change to the readme's setup section

@codecov
Copy link

codecov bot commented Jun 12, 2025

Codecov Report

Attention: Patch coverage is 71.42857% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/api.py 71.42% 2 Missing ⚠️
Files with missing lines Coverage Δ
src/api.py 94.21% <71.42%> (-0.90%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@christe6-osu
Copy link
Author

Sorry, I've been slammed but I am getting back around to this. I removed raise_for_status from src/api.py since it was catching every HTTP response other than 200, and added the general RequestException test that Sourcery recommended.

As for running everything locally, I followed the instructions to run with Docker but without installing Poetry. When I run the container, it gets a ModuleNotFoundError for flask. I have been trying to look into it but my best guess at this point is that my OS or the virtual environment I am using for the project is causing an issue.

@christe6-osu
Copy link
Author

@sourcery-ai review

Copy link
Contributor

@sourcery-ai sourcery-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.

Hey @christe6-osu - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments

### Comment 1
<location> `src/api.py:55` </location>
<code_context>
-    response = requests.get("https://ipinfo.io/json", timeout=10)
+    try:
+        response = requests.get("https://ipinfo.io/json", timeout=10)
+    except requests.exceptions.Timeout:
+        return "No data"
+    except requests.exceptions.RequestException:
</code_context>

<issue_to_address>
Catching Timeout before RequestException is redundant.

Since both exceptions are handled identically, you can just catch RequestException to simplify the code.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    try:
        response = requests.get("https://ipinfo.io/json", timeout=10)
    except requests.exceptions.Timeout:
        return "No data"
    except requests.exceptions.RequestException:
        return "No data"
=======
    try:
        response = requests.get("https://ipinfo.io/json", timeout=10)
    except requests.exceptions.RequestException:
        return "No data"
>>>>>>> REPLACE

</suggested_fix>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +53 to +58
try:
response = requests.get("https://ipinfo.io/json", timeout=10)
except requests.exceptions.Timeout:
return "No data"
except requests.exceptions.RequestException:
return "No data"
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Catching Timeout before RequestException is redundant.

Since both exceptions are handled identically, you can just catch RequestException to simplify the code.

Suggested change
try:
response = requests.get("https://ipinfo.io/json", timeout=10)
except requests.exceptions.Timeout:
return "No data"
except requests.exceptions.RequestException:
return "No data"
try:
response = requests.get("https://ipinfo.io/json", timeout=10)
except requests.exceptions.RequestException:
return "No data"

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.

2 participants