From 9a1ce3e3eb1eb22094d9570e96361056c21a5a60 Mon Sep 17 00:00:00 2001 From: Carson Date: Thu, 16 Apr 2026 19:56:08 -0500 Subject: [PATCH] fix(pkg-py): gracefully handle Snowflake semantic view discovery errors When querychat connects to a Snowflake database that has semantic views but the current role lacks permission to query them (e.g., GET_DDL on a semantic view), the raw SQL call raises a ProgrammingError that propagates up and crashes the Shiny app on startup. Wrap the two SQL execution points in discover_semantic_views() and get_semantic_view_ddl() with try/except so that permission errors (or any other SQL failures) are logged as warnings with full tracebacks instead of crashing the app. The app gracefully degrades to running without semantic view context in the system prompt. Co-Authored-By: Claude Opus 4.6 --- pkg-py/src/querychat/_snowflake.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/pkg-py/src/querychat/_snowflake.py b/pkg-py/src/querychat/_snowflake.py index 381c9cd74..c5992750a 100644 --- a/pkg-py/src/querychat/_snowflake.py +++ b/pkg-py/src/querychat/_snowflake.py @@ -54,7 +54,16 @@ def discover_semantic_views( if os.environ.get("QUERYCHAT_DISABLE_SEMANTIC_VIEWS"): return [] - rows = execute_raw_sql("SHOW SEMANTIC VIEWS", backend) + try: + rows = execute_raw_sql("SHOW SEMANTIC VIEWS", backend) + except Exception: + logger.warning( + "Failed to discover semantic views. " + "This usually means the current role lacks the required privileges. " + "Semantic view context will not be included in the system prompt.", + exc_info=True, + ) + return [] if not rows: logger.debug("No semantic views found in current schema") @@ -83,7 +92,17 @@ def get_semantic_view_ddl( ) -> str | None: """Get DDL for a semantic view by fully qualified name.""" safe_name = fq_name.replace("'", "''") - rows = execute_raw_sql(f"SELECT GET_DDL('SEMANTIC_VIEW', '{safe_name}')", backend) + try: + rows = execute_raw_sql( + f"SELECT GET_DDL('SEMANTIC_VIEW', '{safe_name}')", backend + ) + except Exception: + logger.warning( + "Failed to get DDL for semantic view '%s'. Skipping this view.", + fq_name, + exc_info=True, + ) + return None if rows: return str(next(iter(rows[0].values()))) return None