Skip to content

Fix/log swallowed exceptions#263

Open
dolliecoder wants to merge 2 commits into
AOSSIE-Org:mainfrom
dolliecoder:fix/log-swallowed-exceptions
Open

Fix/log swallowed exceptions#263
dolliecoder wants to merge 2 commits into
AOSSIE-Org:mainfrom
dolliecoder:fix/log-swallowed-exceptions

Conversation

@dolliecoder

@dolliecoder dolliecoder commented Feb 3, 2026

Copy link
Copy Markdown

fixes #259
Replaced except Exception: pass blocks with logger.exception().

Previously, initialization failures were silently ignored, making debugging difficult.
Now errors are logged with stack traces for better observability.

No behavior changes, only improved logging.

Summary by CodeRabbit

  • Performance

    • Embedding operations now execute asynchronously for improved system responsiveness.
  • Chores

    • Enhanced error reporting for graph initialization operations.

@coderabbitai

coderabbitai Bot commented Feb 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Two bug fixes improve error visibility and concurrency: silent exceptions in graph initialization are now logged with descriptive messages, and embedding operations are refactored to execute synchronously in separate threads via asyncio to prevent blocking.

Changes

Cohort / File(s) Summary
Error Logging in Graph Initialization
backend/app/database/falkor/code-graph-backend/api/graph.py
Added module-level logger and replaced silent exception handlers with logger.exception() calls when creating File range index and Searchable fulltext index, enabling error visibility while preserving existing control flow.
Threading for Embedding Operations
backend/app/services/embedding_service/service.py
Introduced asyncio import and private _encode_sync() helper method; refactored get_embedding() and get_embeddings() to execute synchronous model encoding in separate threads via asyncio.to_thread() to prevent blocking.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Whiskers twitching with delight

Errors now reveal their plight,
Logged and visible, shining bright!
Threads dance gently, work flows free,
No more blocking—let it be! 🧵✨

🚥 Pre-merge checks | ✅ 2 | ❌ 3
❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changes implement logging for swallowed exceptions in graph.py as required [#259], but the embedding_service change (asyncio.to_thread) appears unrelated to the logging objective. Verify that asyncio.to_thread changes in embedding_service/service.py align with issue #259 objectives, or move them to a separate PR focused on event loop blocking prevention.
Out of Scope Changes check ⚠️ Warning The asyncio.to_thread changes to embedding_service/service.py address event loop blocking prevention, not the exception logging objective stated in issue #259. Clarify whether event loop optimization is in scope for this PR, or separate it into a dedicated issue/PR with distinct objectives.
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix/log swallowed exceptions' directly matches the main objective—replacing silent exception handling with logging statements in backend initialization code.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dolliecoder

dolliecoder commented Feb 4, 2026

Copy link
Copy Markdown
Author

@smokeyScraper please review it once

@Shevilll Shevilll left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hello @dolliecoder! 👋

This is a fantastic contribution! Replacing silent except Exception: pass blocks with proper logging is a huge step forward for the observability and maintainability of the project, and offloading the CPU-heavy sentence transformer embedding encoding to a separate thread via asyncio.to_thread is an excellent, standard Python concurrency optimization.

Here are a few expert technical notes and design suggestions for this pull request:

🌟 What makes this PR great:

  1. Event Loop Non-Blocking Optimization: Offloading SentenceTransformer.encode to a worker thread using asyncio.to_thread is exactly the right pattern in FastAPI. This ensures concurrent API requests aren't starved while computing high-dimension vector embeddings. Great job!
  2. Eliminating Silent Failures: Exposing previously swallowed exceptions makes debugging development setups immensely easier.

💡 Crucial Best Practice Suggestions:

  1. Handling Expected "Index Already Exists" Errors in FalkorDB:

    • Observation: In graph.py (lines 14–31), when FalkorDB initializes, it attempts to create indexes. If the index was already created during a previous run, FalkorDB's create_node_range_index and create_node_fulltext_index will raise an exception.
    • Problem: Because this exception is completely expected and normal on every startup after the first one, using logger.exception() (which logs at the ERROR level with a full stack traceback) will flood the production logs with tracebacks during normal operation. This can lead to false alarms in error tracking software like Sentry or Datadog.
    • Recommendation: Instead of logging a full traceback at the ERROR level, we can catch the exception and log a simple, friendly info or debug message:
      try:
          self.g.create_node_range_index("File", "name", "ext")
      except Exception as e:
          # Log at INFO/DEBUG level since the index likely already exists
          logger.info("Note: File range index creation skipped or already exists: %s", str(e))
  2. Python Style & PEP 8:

    • The type annotations look clean, and importing asyncio is correctly done.
    • There are a couple of extra double-blank lines introduced in service.py (around lines 67 and 84), which can be quickly cleaned up to keep the formatting extra tidy.

This is a highly impactful PR for both performance and debugging! Thank you for your hard work and contribution to GSoC! 🚀

@Shevilll Shevilll left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Peer Review: Fix/log swallowed exceptions

Hello @dolliecoder! Thank you for addressing the swallowed exceptions issue. Improving observability and logging quality in initialization sequences is extremely helpful for debugging.

I have a feedback item regarding potential false-alarm logs and log flooding:

⚠️ Observation: Log Flooding on Existing Indices

In backend/app/database/falkor/code-graph-backend/api/graph.py, you replaced except Exception: pass with logger.exception(...) during node range and full-text index creation:

        try:
            self.g.create_node_range_index("File", "name", "ext")
        except Exception:
            logger.exception(
                "Failed to create node range index for File(name, ext)"
            )

The Issue:
In FalkorDB / RedisGraph, attempting to create an index that already exists will raise an exception (e.g. Index already exists).
Because graph initialization runs every time the application starts up or when a new graph context is established, this means every subsequent run of the server will log a massive ERROR log with a full traceback/stack trace simply because the indices were already created in a previous session.
This leads to:

  1. Log pollution: Cluttering standard error output and log-aggregation systems with false alarms.
  2. Alert fatigue: Devs/SREs might see ERROR with traceback and waste time investigating a non-issue.

💡 Suggested Fix

We can selectively silence or log a brief info/debug message if the exception is due to the index already existing, while still logging full tracebacks for unexpected actual failures.

For example, we can check the exception message:

        try:
            self.g.create_node_range_index("File", "name", "ext")
        except Exception as e:
            if "already exists" in str(e).lower():
                logger.info("Node range index for File(name, ext) already exists.")
            else:
                logger.exception(
                    "Unexpected failure creating node range index for File(name, ext)"
                )

This keeps the logs clean during normal operations (where the index already exists) while fully preserving the observability benefits of your PR for genuine failures (e.g., connection drops, permission issues, or syntactical errors).

What are your thoughts on this approach? Thanks again for your work!

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.

BUG: Silent Exceptions in Backend Initialization Are Not Logged

2 participants