Skip to content

Commit 7a3c31f

Browse files
committed
chore: catch segfault on connect
1 parent 3d75632 commit 7a3c31f

File tree

5 files changed

+24
-3
lines changed

5 files changed

+24
-3
lines changed

aws_advanced_python_wrapper/default_plugin.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from __future__ import annotations
1616

17+
import signal
1718
from typing import TYPE_CHECKING, List, Optional
1819

1920
if TYPE_CHECKING:
@@ -28,7 +29,7 @@
2829
import copy
2930
from typing import Any, Callable, Set
3031

31-
from aws_advanced_python_wrapper.errors import AwsWrapperError
32+
from aws_advanced_python_wrapper.errors import AwsWrapperError, SegfaultOnConnectError
3233
from aws_advanced_python_wrapper.host_availability import HostAvailability
3334
from aws_advanced_python_wrapper.hostinfo import HostInfo, HostRole
3435
from aws_advanced_python_wrapper.plugin import Plugin
@@ -40,10 +41,17 @@
4041
class DefaultPlugin(Plugin):
4142
_SUBSCRIBED_METHODS: Set[str] = {"*"}
4243
_CLOSE_METHOD = "Connection.close"
44+
_in_connect = False
4345

4446
def __init__(self, plugin_service: PluginService, connection_provider_manager: ConnectionProviderManager):
4547
self._plugin_service: PluginService = plugin_service
4648
self._connection_provider_manager = connection_provider_manager
49+
signal.signal(signal.SIGSEGV, self._segfault_handler)
50+
51+
def _segfault_handler(self, signum, frame):
52+
if DefaultPlugin._in_connect:
53+
raise SegfaultOnConnectError(Messages.get("DefaultPlugin.SegFault"))
54+
signal.default_int_handler(signum, frame)
4755

4856
def connect(
4957
self,
@@ -71,9 +79,11 @@ def _connect(
7179

7280
conn: Connection
7381
try:
82+
DefaultPlugin._in_connect = True
7483
database_dialect = self._plugin_service.database_dialect
7584
conn = conn_provider.connect(target_func, driver_dialect, database_dialect, host_info, props)
7685
finally:
86+
DefaultPlugin._in_connect = False
7787
context.close_context()
7888

7989
self._plugin_service.set_availability(host_info.all_aliases, HostAvailability.AVAILABLE)

aws_advanced_python_wrapper/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,7 @@ class FailoverSuccessError(FailoverError):
4545

4646
class ReadWriteSplittingError(AwsWrapperError):
4747
__module__ = "aws_advanced_python_wrapper"
48+
49+
50+
class SegfaultOnConnectError(AwsWrapperError):
51+
__module__ = "aws_advanced_python_wrapper"

aws_advanced_python_wrapper/resources/aws_advanced_python_wrapper_messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ CustomEndpointPlugin.WaitingForCustomEndpointInfo=[CustomEndpointPlugin] Custom
9999

100100
DefaultPlugin.EmptyHosts=[DefaultPlugin] The default connection plugin received an empty host list from the plugin service.
101101
DefaultPlugin.UnknownHosts=[DefaultPlugin] A HostInfo with the role of HostRole.UNKNOWN was requested via get_host_info_by_strategy. The requested role must be either HostRole.WRITER or HostRole.READER.
102+
DefaultPlugin.SegFault=[DefaultPlugin] Segmentation fault thrown during connect
102103

103104
DefaultTelemetryFactory.InvalidMetricsBackend=[DefaultTelemetryFactory] {} is not a valid metrics backend. Available options: OTLP, NONE.
104105
DefaultTelemetryFactory.InvalidTracingBackend=[DefaultTelemetryFactory] {} is not a valid tracing backend. Available options: OTLP, XRAY, NONE.

aws_advanced_python_wrapper/utils/mysql_exception_handler.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
from mysql.connector import DatabaseError, InterfaceError
1818

19-
from aws_advanced_python_wrapper.errors import QueryTimeoutError
19+
from aws_advanced_python_wrapper.errors import QueryTimeoutError, SegfaultOnConnectError
2020
from aws_advanced_python_wrapper.exception_handling import ExceptionHandler
2121

2222

@@ -37,6 +37,9 @@ class MySQLExceptionHandler(ExceptionHandler):
3737
]
3838

3939
def is_network_exception(self, error: Optional[Exception] = None, sql_state: Optional[str] = None) -> bool:
40+
if isinstance(error, SegfaultOnConnectError):
41+
return True
42+
4043
if isinstance(error, QueryTimeoutError):
4144
return True
4245

aws_advanced_python_wrapper/utils/pg_exception_handler.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
InvalidAuthorizationSpecification, InvalidPassword,
1919
OperationalError)
2020

21-
from aws_advanced_python_wrapper.errors import QueryTimeoutError
21+
from aws_advanced_python_wrapper.errors import QueryTimeoutError, SegfaultOnConnectError
2222
from aws_advanced_python_wrapper.exception_handling import ExceptionHandler
2323

2424

@@ -42,6 +42,9 @@ class PgExceptionHandler(ExceptionHandler):
4242
_ACCESS_ERROR_CODES: List[str]
4343

4444
def is_network_exception(self, error: Optional[Exception] = None, sql_state: Optional[str] = None) -> bool:
45+
if isinstance(error, SegfaultOnConnectError):
46+
return True
47+
4548
if isinstance(error, QueryTimeoutError) or isinstance(error, ConnectionTimeout):
4649
return True
4750
if sql_state is None:

0 commit comments

Comments
 (0)