@@ -199,6 +199,7 @@ def _get_connection(self):
199199
200200 max_retries = 3
201201 for attempt in range (max_retries ):
202+ conn = None
202203 try :
203204 conn = self .connection_pool .getconn ()
204205
@@ -216,8 +217,49 @@ def _get_connection(self):
216217
217218 # Set autocommit for PolarDB compatibility
218219 conn .autocommit = True
220+
221+ # Test connection health with SELECT 1
222+ try :
223+ cursor = conn .cursor ()
224+ cursor .execute ("SELECT 1" )
225+ cursor .fetchone ()
226+ cursor .close ()
227+ except Exception as health_check_error :
228+ # Connection is not usable, close it and try again
229+ logger .warning (
230+ f"Connection health check failed: { health_check_error } , closing connection and retrying..."
231+ )
232+ try :
233+ conn .close ()
234+ except Exception as close_error :
235+ logger .warning (f"Failed to close unhealthy connection: { close_error } " )
236+
237+ # Return connection to pool if it's still valid
238+ try :
239+ self .connection_pool .putconn (conn , close = True )
240+ except Exception as close_error :
241+ logger .warning (f"Failed to connection_pool.putconn: { close_error } " )
242+
243+ conn = None
244+ if attempt < max_retries - 1 :
245+ continue
246+ else :
247+ raise RuntimeError (
248+ f"Failed to get a healthy connection from pool after { max_retries } attempts: { health_check_error } "
249+ ) from health_check_error
250+
251+ # Connection is healthy, return it
219252 return conn
220253 except Exception as e :
254+ # If we have a connection that failed, try to return it to pool
255+ if conn is not None :
256+ try :
257+ self .connection_pool .putconn (conn , close = True )
258+ except Exception as putconn_error :
259+ logger .warning (
260+ f"Failed to connection_pool.putconn to pool: { putconn_error } "
261+ )
262+
221263 if attempt >= max_retries - 1 :
222264 raise RuntimeError (f"Failed to get a valid connection from pool: { e } " ) from e
223265 continue
@@ -647,12 +689,16 @@ def add_edge(
647689 self , source_id : str , target_id : str , type : str , user_name : str | None = None
648690 ) -> None :
649691 if not source_id or not target_id :
692+ logger .warning (f"Edge '{ source_id } ' and '{ target_id } ' are both None" )
650693 raise ValueError ("[add_edge] source_id and target_id must be provided" )
651694
652695 source_exists = self .get_node (source_id ) is not None
653696 target_exists = self .get_node (target_id ) is not None
654697
655698 if not source_exists or not target_exists :
699+ logger .warning (
700+ "[add_edge] Source %s or target %s does not exist." , source_exists , target_exists
701+ )
656702 raise ValueError ("[add_edge] source_id and target_id must be provided" )
657703
658704 properties = {}
0 commit comments