Skip to content

Conversation

@rakshitjain23
Copy link

@rakshitjain23 rakshitjain23 commented Dec 17, 2025

I fixed an issue where the QR code for rooms was always showing localhost instead of the actual site URL. I updated the settings logic so it now correctly uses the configured domain (like test.eventyay.com) if a short URL isn't explicitly set.

Also, I found that if the BigBlueButton server isn't set up (which happens often in local dev), the whole WebSocket connection would crash. This side effect was causing other features, like the QR code generation, to fail or load infinitely. I added a check to handle this error gracefully so the app stays stable even without a video server.

Result:

QR codes now point to the correct domain instead of localhost.
The app no longer crashes/freezes when checking for the video server.

Screenshots:

Before:
Screenshot from 2025-12-17 12-43-20
After:
Screenshot from 2025-12-17 13-09-42

#1526

Summary by Sourcery

Handle missing BigBlueButton configuration more gracefully and align QR code short URL behavior with the primary site URL configuration.

Bug Fixes:

  • Prevent WebSocket handlers for BigBlueButton rooms, calls, and recordings from crashing when no BBB server is configured by surfacing a controlled error instead.
  • Ensure QR code and other short URL consumers use the main site URL when no explicit short_url is configured.

Enhancements:

  • Allow short_url configuration to be optional and automatically default to site_url via a settings model validator.

- Fix: Ensure  defaults  to  if not explicitly set, fixing incorrect QR codes (localhost).
- Fix: Determine  dynamically from environment variables in production.
- Refactor: Add  in  to prevent WebSocket consumer crashes when the video server is unconfigured (common in dev/partial deployments).
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 17, 2025

Reviewer's Guide

Adds defensive handling around BigBlueButton (BBB) interactions to prevent WebSocket crashes when BBB is not configured, and updates settings so QR codes use the configured site URL as the default short URL instead of always localhost.

Sequence diagram for BBB WebSocket error handling and URL generation

sequenceDiagram
    actor WebClient
    participant WebSocketConsumer
    participant BBBModule
    participant BBBService

    WebClient->>WebSocketConsumer: send room_url request
    WebSocketConsumer->>BBBModule: room_url(body)
    BBBModule->>BBBService: get_join_url_for_room(room, user, moderator)
    BBBService-->>BBBModule: IntegrityError
    BBBModule->>WebSocketConsumer: raise ConsumerException bbb.failed
    WebSocketConsumer-->>WebClient: error response bbb.failed

    WebClient->>WebSocketConsumer: send call_url request
    WebSocketConsumer->>BBBModule: call_url(body)
    BBBModule->>BBBService: get_join_url_for_call_id(call_id, user)
    BBBService-->>BBBModule: IntegrityError
    BBBModule->>WebSocketConsumer: raise ConsumerException bbb.failed
    WebSocketConsumer-->>WebClient: error response bbb.failed

    WebClient->>WebSocketConsumer: send recordings request
    WebSocketConsumer->>BBBModule: recordings(body)
    BBBModule->>BBBService: get_recordings_for_room(room)
    BBBService-->>BBBModule: IntegrityError
    BBBModule-->>WebSocketConsumer: recordings = []
    WebSocketConsumer-->>WebClient: success response results = []
Loading

Class diagram for updated BaseSettings and short_url defaulting

classDiagram
    class BaseSettings {
        HttpUrl site_url
        HttpUrl short_url
        str talk_hostname
        str sentry_dsn
        str instance_name
        str zoom_key
        str zoom_secret
        str control_secret
        str statsd_host
        int statsd_port
        str statsd_prefix
        BaseSettings default_short_url()
    }

    class _BaseSettings {
    }

    BaseSettings --|> _BaseSettings

    class default_short_url {
        +BaseSettings __call__(BaseSettings self)
    }

    BaseSettings ..> default_short_url
Loading

File-Level Changes

Change Details Files
Harden BBB WebSocket handlers against missing/misconfigured BBB server so the consumer fails gracefully instead of crashing.
  • Wrap BBB join URL generation in a try/except catching IntegrityError and convert it to a ConsumerException with a generic failure message.
  • Do the same IntegrityError handling for call-based join URL generation to ensure a consistent error path.
  • Wrap BBB recordings retrieval in a try/except catching IntegrityError and fall back to an empty recordings list when BBB is unavailable.
app/eventyay/features/live/modules/bbb.py
Make short_url configuration optional and default to site_url so generated URLs (e.g., QR codes) use the correct domain when no explicit short URL is set.
  • Change short_url setting type from HttpUrl to Optional[HttpUrl] with a default of None.
  • Add a Pydantic model_validator that, after initialization, sets short_url to site_url when short_url is not provided.
  • Keep existing URL-related settings (site_url, talk_hostname) unchanged so only short_url behavior is updated.
app/eventyay/config/next_settings.py

Possibly linked issues

  • #(not provided): PR changes URL settings so QR codes use site_url/short_url instead of localhost, matching issue report.

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

@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 there - I've reviewed your changes - here's some feedback:

  • The new IntegrityError handling in the BBB handlers is very broad; consider catching a BBB-specific exception or at least logging the IntegrityError so genuine data issues in production don’t get silently converted into generic bbb.failed responses.
  • In the recordings handler, swallowing IntegrityError and returning an empty list changes the semantics compared to the other handlers that raise bbb.failed; it might be clearer to surface a controlled error instead of silently returning no recordings.
  • There appears to be an indentation issue in the except IntegrityError: block for recordings (recordings = [] has an extra leading space) which could cause linting or readability problems; align this line with the rest of the block.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new IntegrityError handling in the BBB handlers is very broad; consider catching a BBB-specific exception or at least logging the IntegrityError so genuine data issues in production don’t get silently converted into generic `bbb.failed` responses.
- In the `recordings` handler, swallowing IntegrityError and returning an empty list changes the semantics compared to the other handlers that raise `bbb.failed`; it might be clearer to surface a controlled error instead of silently returning no recordings.
- There appears to be an indentation issue in the `except IntegrityError:` block for `recordings` (`recordings = []` has an extra leading space) which could cause linting or readability problems; align this line with the rest of the block.

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
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 addresses two distinct issues: fixing QR code URL generation to use the configured site domain instead of localhost, and improving WebSocket stability when BigBlueButton servers are not configured.

Key Changes:

  • Modified settings to make short_url optional and default to site_url via a model validator
  • Added exception handling in BBB WebSocket handlers to prevent crashes when no BBB server is configured

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
app/eventyay/config/next_settings.py Changed short_url to optional (None allowed) and added a model validator that defaults it to site_url when not explicitly set
app/eventyay/features/live/modules/bbb.py Wrapped BBB service calls in try-except blocks to catch IntegrityError and gracefully handle missing BBB server configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

self.room,
)
except IntegrityError:
recordings = []
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

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

There is an extra space before 'recordings' causing incorrect indentation. This line should align with the 'except' block above it.

Suggested change
recordings = []
recordings = []

Copilot uses AI. Check for mistakes.
Comment on lines 34 to 36
except IntegrityError:
# This happens in dev environment when no BBB server is configured
raise ConsumerException("bbb.failed")
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

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

Catching IntegrityError here is too broad and may mask other database integrity issues. The actual problem occurs when choose_server() returns None (no BBB servers configured), which causes the BBBCall.server foreign key constraint to fail. Consider catching a more specific exception or checking if server is None in the get_create_params_for_room function instead.

Copilot uses AI. Check for mistakes.
Comment on lines 47 to 53
try:
url = await service.get_join_url_for_call_id(
body.get("call"),
self.consumer.user,
)
except IntegrityError:
raise ConsumerException("bbb.failed")
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

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

Catching IntegrityError here is too broad and may mask other database integrity issues. The actual problem occurs when choose_server() returns None (no BBB servers configured), which causes the BBBCall.server foreign key constraint to fail. Consider catching a more specific exception or checking if server is None in the get_create_params_for_call_id function instead.

Suggested change
try:
url = await service.get_join_url_for_call_id(
body.get("call"),
self.consumer.user,
)
except IntegrityError:
raise ConsumerException("bbb.failed")
url = await service.get_join_url_for_call_id(
body.get("call"),
self.consumer.user,
)

Copilot uses AI. Check for mistakes.
Comment on lines 66 to 71
try:
recordings = await service.get_recordings_for_room(
self.room,
)
except IntegrityError:
recordings = []
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

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

The recordings method is unlikely to raise IntegrityError since it doesn't create or update any BBBCall records - it only queries for recordings. The get_recordings_for_room method already has comprehensive exception handling that returns an empty list on errors. This try-except block appears unnecessary and may give a false sense of error handling.

Suggested change
try:
recordings = await service.get_recordings_for_room(
self.room,
)
except IntegrityError:
recordings = []
recordings = await service.get_recordings_for_room(
self.room,
)

Copilot uses AI. Check for mistakes.
Comment on lines 150 to 154
@model_validator(mode='after')
def default_short_url(self) -> 'BaseSettings':
if self.short_url is None:
self.short_url = self.site_url
return self
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

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

The model_validator is placed in the middle of field definitions, between control_secret and statsd_host. For better code organization and readability, consider moving all validators to the end of the class after all field definitions, or grouping them with related fields.

Copilot uses AI. Check for mistakes.
@rakshitjain23
Copy link
Author

@ArnavBallinCode hey any changes needed?

Copy link
Member

@hongquan hongquan left a comment

Choose a reason for hiding this comment

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

Please address the Copilot review.

I don't want the short_url to accept None. If you find that the cause of this bug is that people forgot to set short_url, then just provide the default value in the *.toml files.

@rakshitjain23
Copy link
Author

@hongquan I've ensured short_url no longer accepts None. I removed the validator and instead explicitly added short_url to both eventyay.development.toml and eventyay.production.toml with appropriate default values.
bbb.py - improvements: I removed the broad try...except IntegrityError blocks and fixed the indentation issues as pointed out.

Copy link
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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

app/eventyay/config/next_settings.py:16

  • Import of 'model_validator' is not used.
from pydantic import Field, HttpUrl, model_validator

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

from kombu import Queue
from pycountry import currencies
from pydantic import Field, HttpUrl
from pydantic import Field, HttpUrl, model_validator
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

The model_validator import is not used anywhere in this file. According to the PR description, a model validator should be implemented to automatically default short_url to site_url when not explicitly configured, but no such validator has been added. Either implement the validator or remove this unused import.

Suggested change
from pydantic import Field, HttpUrl, model_validator
from pydantic import Field, HttpUrl

Copilot uses AI. Check for mistakes.
Copy link
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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@rakshitjain23
Copy link
Author

rakshitjain23 commented Dec 19, 2025

@mariobehling any changes needed? or it'll be closed?

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.

3 participants