(self, address: _Address, err_ctx: _ErrorContext)
| 859 | return _is_stale_error_topology_version(cur_tv, error_tv) |
| 860 | |
| 861 | async def _handle_error(self, address: _Address, err_ctx: _ErrorContext) -> None: |
| 862 | if self._is_stale_error(address, err_ctx): |
| 863 | return |
| 864 | |
| 865 | server = self._servers[address] |
| 866 | error = err_ctx.error |
| 867 | service_id = err_ctx.service_id |
| 868 | |
| 869 | # Ignore a handshake error if the server is behind a load balancer but |
| 870 | # the service ID is unknown. This indicates that the error happened |
| 871 | # when dialing the connection or during the MongoDB handshake, so we |
| 872 | # don't know the service ID to use for clearing the pool. |
| 873 | if self._settings.load_balanced and not service_id and not err_ctx.completed_handshake: |
| 874 | return |
| 875 | |
| 876 | if isinstance(error, NetworkTimeout) and err_ctx.completed_handshake: |
| 877 | # The socket has been closed. Don't reset the server. |
| 878 | # Server Discovery And Monitoring Spec: "When an application |
| 879 | # operation fails because of any network error besides a socket |
| 880 | # timeout...." |
| 881 | return |
| 882 | elif isinstance(error, WriteError): |
| 883 | # Ignore writeErrors. |
| 884 | return |
| 885 | elif isinstance(error, (NotPrimaryError, OperationFailure)): |
| 886 | # As per the SDAM spec if: |
| 887 | # - the server sees a "not primary" error, and |
| 888 | # - the server is not shutting down, and |
| 889 | # - the server version is >= 4.2, then |
| 890 | # we keep the existing connection pool, but mark the server type |
| 891 | # as Unknown and request an immediate check of the server. |
| 892 | # Otherwise, we clear the connection pool, mark the server as |
| 893 | # Unknown and request an immediate check of the server. |
| 894 | if hasattr(error, "code"): |
| 895 | err_code = error.code |
| 896 | else: |
| 897 | # Default error code if one does not exist. |
| 898 | default = 10107 if isinstance(error, NotPrimaryError) else None |
| 899 | err_code = error.details.get("code", default) # type: ignore[union-attr] |
| 900 | if err_code in helpers_shared._NOT_PRIMARY_CODES: |
| 901 | is_shutting_down = err_code in helpers_shared._SHUTDOWN_CODES |
| 902 | # Mark server Unknown, clear the pool, and request check. |
| 903 | if not self._settings.load_balanced: |
| 904 | await self._process_change(ServerDescription(address, error=error)) |
| 905 | if is_shutting_down or (err_ctx.max_wire_version <= 7): |
| 906 | # Clear the pool. |
| 907 | await server.reset(service_id) |
| 908 | server.request_check() |
| 909 | elif not err_ctx.completed_handshake: |
| 910 | # Unknown command error during the connection handshake. |
| 911 | if not self._settings.load_balanced: |
| 912 | await self._process_change(ServerDescription(address, error=error)) |
| 913 | # Clear the pool. |
| 914 | await server.reset(service_id) |
| 915 | elif isinstance(error, ConnectionFailure): |
| 916 | if isinstance(error, WaitQueueTimeoutError) or ( |
| 917 | error.has_error_label("SystemOverloadedError") |
| 918 | ): |
no test coverage detected