33from typing import Optional
44
55import click
6+ from redis .exceptions import ConnectionError as RedisConnectionError
7+ from redis .exceptions import TimeoutError as RedisTimeoutError
68
79from ...settings import get_root_migrations_dir
810from ..migrations .schema_migrator import SchemaMigrator
@@ -17,6 +19,38 @@ def run_async(coro):
1719 return future .result ()
1820
1921
22+ def handle_redis_errors (func ):
23+ """Decorator to handle Redis connection and timeout errors with user-friendly messages."""
24+ import functools
25+
26+ @functools .wraps (func )
27+ def wrapper (* args , ** kwargs ):
28+ try :
29+ return func (* args , ** kwargs )
30+ except RedisConnectionError as e :
31+ click .echo ("Error: Could not connect to Redis." , err = True )
32+ click .echo ("Please ensure Redis is running and accessible." , err = True )
33+ if "localhost:6379" in str (e ):
34+ click .echo ("Trying to connect to: localhost:6379 (default)" , err = True )
35+ click .echo (
36+ f"Connection details: { str (e ).split ('connecting to' )[- 1 ].strip () if 'connecting to' in str (e ) else 'N/A' } " ,
37+ err = True ,
38+ )
39+ raise SystemExit (1 )
40+ except RedisTimeoutError :
41+ click .echo ("Error: Redis connection timed out." , err = True )
42+ click .echo (
43+ "Please check your Redis server status and network connectivity." ,
44+ err = True ,
45+ )
46+ raise SystemExit (1 )
47+ except Exception as e :
48+ # Re-raise other exceptions unchanged
49+ raise e
50+
51+ return wrapper
52+
53+
2054@click .group ()
2155def migrate ():
2256 """Manage schema migrations for Redis OM models."""
@@ -25,6 +59,7 @@ def migrate():
2559
2660@migrate .command ()
2761@click .option ("--migrations-dir" , help = "Directory containing schema migration files" )
62+ @handle_redis_errors
2863def status (migrations_dir : Optional [str ]):
2964 """Show current schema migration status from files."""
3065 dir_path = migrations_dir or os .path .join (
@@ -62,6 +97,7 @@ def status(migrations_dir: Optional[str]):
6297 is_flag = True ,
6398 help = "Skip confirmation prompt to create directory or run" ,
6499)
100+ @handle_redis_errors
65101def run (
66102 migrations_dir : Optional [str ],
67103 dry_run : bool ,
@@ -110,6 +146,7 @@ def run(
110146@click .option (
111147 "--yes" , "-y" , is_flag = True , help = "Skip confirmation prompt to create directory"
112148)
149+ @handle_redis_errors
113150def create (name : str , migrations_dir : Optional [str ], yes : bool ):
114151 """Create a new schema migration snapshot file from current pending operations."""
115152 dir_path = migrations_dir or os .path .join (
@@ -144,6 +181,7 @@ def create(name: str, migrations_dir: Optional[str], yes: bool):
144181 is_flag = True ,
145182 help = "Skip confirmation prompt to create directory or run" ,
146183)
184+ @handle_redis_errors
147185def rollback (
148186 migration_id : str ,
149187 migrations_dir : Optional [str ],
0 commit comments