99from contextlib import asynccontextmanager
1010import asyncio
1111import logging
12+ import sys
13+ import traceback
1214
1315from yarl import URL
1416import asyncpg
@@ -23,6 +25,7 @@ class PostgresDatabase(Database):
2325 scheme = Scheme .POSTGRES
2426 _pool : asyncpg .pool .Pool | None
2527 _pool_override : bool
28+ _exit_on_ice : bool
2629
2730 def __init__ (
2831 self ,
@@ -37,6 +40,7 @@ def __init__(
3740 self .scheme = Scheme .COCKROACH
3841 # Send postgres scheme to asyncpg
3942 url = url .with_scheme ("postgres" )
43+ self ._exit_on_ice = (db_args or {}).pop ("meow_exit_on_ice" , True )
4044 super ().__init__ (
4145 url ,
4246 db_args = db_args ,
@@ -72,10 +76,26 @@ async def stop(self) -> None:
7276 if not self ._pool_override and self ._pool is not None :
7377 await self ._pool .close ()
7478
79+ async def _handle_exception (self , err : Exception ) -> None :
80+ if self ._exit_on_ice and isinstance (err , asyncpg .InternalClientError ):
81+ pre_stack = traceback .format_stack ()[:- 2 ]
82+ post_stack = traceback .format_exception (err )
83+ header = post_stack [0 ]
84+ post_stack = post_stack [1 :]
85+ self .log .critical (
86+ "Got asyncpg internal client error, exiting...\n %s%s%s" ,
87+ header ,
88+ "" .join (pre_stack ),
89+ "" .join (post_stack ),
90+ )
91+ sys .exit (26 )
92+
7593 @asynccontextmanager
7694 async def acquire (self ) -> LoggingConnection :
7795 async with self .pool .acquire () as conn :
78- yield LoggingConnection (self .scheme , conn , self .log )
96+ yield LoggingConnection (
97+ self .scheme , conn , self .log , handle_exception = self ._handle_exception
98+ )
7999
80100
81101Database .schemes ["postgres" ] = PostgresDatabase
0 commit comments