Skip to content

fix: Add timeout, extract constant, harden avatar URL parsing, and use module-level logging#3481

Open
AliRana30 wants to merge 1 commit intofossasia:devfrom
AliRana30:fix/social-avatar-download-timeout
Open

fix: Add timeout, extract constant, harden avatar URL parsing, and use module-level logging#3481
AliRana30 wants to merge 1 commit intofossasia:devfrom
AliRana30:fix/social-avatar-download-timeout

Conversation

@AliRana30
Copy link
Copy Markdown

@AliRana30 AliRana30 commented May 6, 2026

Description

This change improves reliability and observability of social avatar downloads by:

  • Adding a 10‑second timeout to avatar HTTP downloads to avoid long hangs and resource leaks.
  • Extracting the timeout value to a named constant (SOCIAL_AVATAR_DOWNLOAD_TIMEOUT) for reuse and easy
    adjustment.
  • Improving URL extension parsing so query strings and malformed URLs are handled safely (extracts extension after path,
    strips query/fragment, and falls back to a safe default when required).
  • Switching to module-level logging (logger = logging.getLogger(name)) for consistent, testable diagnostic messages.

Changes

  • Add EXTERNAL_REQUEST_TIMEOUT = 10 constant for reusable outbound request timeout across social sync code
  • Replace naive avatar_url.rsplit(".", 1)[-1] with urlparse(...).path + os.path.splitext(...) to safely handle query params (e.g., jpg?e=12345) and ambiguous URLs
  • Switch from root logging.exception() to module-level logger.exception() for consistent namespacing during social profile sync
  • Narrow exception handling from bare except: to requests.RequestException only

Before

ext = avatar_url.rsplit(".", 1)[-1]
if "/" in ext:
    ext = ".png"
try:
    r = requests.get(avatar_url)  # no timeout
    ...
except:  # swallows all exceptions
    logging.exception("Could not download avatar")
 

After

path = urlparse(avatar_url).path
ext = os.path.splitext(path)[1].lstrip('.')
if not ext or '/' in ext or '?' in ext:
    ext = 'png'
try:
    r = requests.get(avatar_url, timeout=EXTERNAL_REQUEST_TIMEOUT)
    ...
except requests.RequestException:
    logger.exception("Could not download avatar")   

Closes : #3492

Copilot AI review requested due to automatic review settings May 6, 2026 18:56
@github-project-automation github-project-automation Bot moved this to Backlog in Eventyay Next May 6, 2026
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 6, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Narrowly scope exception handling in social avatar downloads and ticket secret parsing to avoid swallowing unexpected errors, add timeouts and logging for better diagnostics, and keep existing user-visible behavior consistent.

Sequence diagram for social avatar download with timeout and scoped exception handling

sequenceDiagram
    actor User
    participant WebApp
    participant SocialUtils
    participant Requests
    participant AvatarServer
    participant StoredFile
    participant Logging

    User->>WebApp: Authenticate via social provider
    WebApp->>SocialUtils: update_user_profile_from_social(user, info, backend)
    SocialUtils->>Requests: get(avatar_url, timeout=10)
    Requests->>AvatarServer: HTTP GET avatar_url
    alt Request succeeds
        AvatarServer-->>Requests: 200 OK + image bytes
        Requests-->>SocialUtils: Response
        SocialUtils->>Requests: raise_for_status()
        SocialUtils->>StoredFile: StoredFile.objects.create(..., type=avatar, public=True)
        StoredFile-->>SocialUtils: StoredFile instance
        SocialUtils->>StoredFile: file.save(avatar.ext, content)
        SocialUtils-->>WebApp: Updated user profile with avatar
    else Request fails or times out
        Requests-->>SocialUtils: Raise RequestException
        SocialUtils->>Logging: logging.exception(Could not download avatar)
        SocialUtils-->>WebApp: User profile unchanged (no avatar update)
    end
Loading

Class diagram for social avatar update and Sig1TicketSecretGenerator parsing changes

classDiagram

    class SocialUtils {
        +update_user_profile_from_social(user, info, backend)
    }

    class Sig1TicketSecretGenerator {
        -logger
        +_parse(secret)
    }

    class RequestsLibrary {
        +get(url, timeout)
    }

    class LoggingModule {
        +exception(message)
        +debug(message, error)
    }

    class StoredFile {
        +objects
        +file
        +save(name, content)
    }

    class StoredFileManager {
        +create(name, base_folder, type, public)
    }

    class Sig1TicketSecretExceptions {
        binasciiError
        structError
        valueError
        typeError
        invalidSignature
        indexError
        decodeError
    }

    SocialUtils --> RequestsLibrary : uses
    SocialUtils --> StoredFile : creates
    SocialUtils --> LoggingModule : logs_download_failure

    Sig1TicketSecretGenerator --> LoggingModule : logs_parse_failure
    Sig1TicketSecretGenerator --> Sig1TicketSecretExceptions : catches

    StoredFile o-- StoredFileManager : objects
Loading

File-Level Changes

Change Details Files
Harden Sig1 ticket secret parsing by catching only expected parsing/crypto errors and logging them while preserving the None-on-failure behavior.
  • Replaced bare except in Sig1TicketSecretGenerator._parse with a specific tuple of expected exceptions for decoding and signature validation failures
  • Added debug logging to record parsing and crypto failures with full exception info
  • Imported logging, binascii, InvalidSignature, and DecodeError to support the more precise error handling and logging behavior
app/eventyay/base/secrets.py
Make social avatar downloads more robust and observable by adding a timeout and constraining exception handling to HTTP-related errors only.
  • Updated avatar download to call requests.get with a 10-second timeout to avoid hanging on slow or unresponsive endpoints
  • Replaced bare except with except requests.RequestException to avoid swallowing unrelated exceptions while still handling network/HTTP errors
  • Ensured logging.exception is still invoked when avatar downloads fail
app/eventyay/features/social/utils.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
Copy Markdown
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 - I've left some high level feedback:

  • Consider extracting the timeout=10 value into a named constant or configuration setting so it’s easier to tune or reuse across other outbound requests.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider extracting the `timeout=10` value into a named constant or configuration setting so it’s easier to tune or reuse across other outbound requests.

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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the social-profile avatar fetch path to avoid hanging on slow/unresponsive avatar URLs by applying a request timeout and narrowing the exception handler to requests.RequestException.

Changes:

  • Add a 10s timeout to the avatar requests.get() call.
  • Replace a bare except: with except requests.RequestException for avatar download failures.

Comment thread app/eventyay/features/social/utils.py Outdated
Comment thread app/eventyay/features/social/utils.py Outdated
Comment thread app/eventyay/features/social/utils.py Outdated
@ViRUS-0-0
Copy link
Copy Markdown
Contributor

Hi @AliRana30, Please mention the issue you are fixing in the PR description.

@AliRana30 AliRana30 force-pushed the fix/social-avatar-download-timeout branch from 80649d6 to 3777b85 Compare May 7, 2026 11:40
@AliRana30 AliRana30 changed the title fix: timeout avatar download requests fix: Add timeout, extract constant, harden avatar URL parsing, and use module-level logging May 7, 2026
@AliRana30
Copy link
Copy Markdown
Author

AliRana30 commented May 8, 2026

hi @ViRUS-0-0, @Aqil-Ahmad! You can review the PR, I have added everything as requested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

Social avatar downloads hang indefinitely without timeout

3 participants