| 2233 | _is_disconnect = False |
| 2234 | |
| 2235 | def _handle_dbapi_exception( |
| 2236 | self, |
| 2237 | e: BaseException, |
| 2238 | statement: Optional[str], |
| 2239 | parameters: Optional[_AnyExecuteParams], |
| 2240 | cursor: Optional[DBAPICursor], |
| 2241 | context: Optional[ExecutionContext], |
| 2242 | is_sub_exec: bool = False, |
| 2243 | ) -> NoReturn: |
| 2244 | exc_info = sys.exc_info() |
| 2245 | |
| 2246 | is_exit_exception = util.is_exit_exception(e) |
| 2247 | |
| 2248 | if not self._is_disconnect: |
| 2249 | self._is_disconnect = ( |
| 2250 | isinstance(e, self.dialect.loaded_dbapi.Error) |
| 2251 | and not self.closed |
| 2252 | and self.dialect.is_disconnect( |
| 2253 | e, |
| 2254 | self._dbapi_connection if not self.invalidated else None, |
| 2255 | cursor, |
| 2256 | ) |
| 2257 | ) or (is_exit_exception and not self.closed) |
| 2258 | |
| 2259 | invalidate_pool_on_disconnect = not is_exit_exception |
| 2260 | |
| 2261 | ismulti: bool = ( |
| 2262 | not is_sub_exec and context.executemany |
| 2263 | if context is not None |
| 2264 | else False |
| 2265 | ) |
| 2266 | if self._reentrant_error: |
| 2267 | raise exc.DBAPIError.instance( |
| 2268 | statement, |
| 2269 | parameters, |
| 2270 | e, |
| 2271 | self.dialect.loaded_dbapi.Error, |
| 2272 | hide_parameters=self.engine.hide_parameters, |
| 2273 | dialect=self.dialect, |
| 2274 | ismulti=ismulti, |
| 2275 | ).with_traceback(exc_info[2]) from e |
| 2276 | self._reentrant_error = True |
| 2277 | try: |
| 2278 | # non-DBAPI error - if we already got a context, |
| 2279 | # or there's no string statement, don't wrap it |
| 2280 | should_wrap = isinstance(e, self.dialect.loaded_dbapi.Error) or ( |
| 2281 | statement is not None |
| 2282 | and context is None |
| 2283 | and not is_exit_exception |
| 2284 | ) |
| 2285 | |
| 2286 | if should_wrap: |
| 2287 | sqlalchemy_exception = exc.DBAPIError.instance( |
| 2288 | statement, |
| 2289 | parameters, |
| 2290 | cast(Exception, e), |
| 2291 | self.dialect.loaded_dbapi.Error, |
| 2292 | hide_parameters=self.engine.hide_parameters, |