Handle errors raised when executing an operation.
| 2663 | |
| 2664 | |
| 2665 | class _MongoClientErrorHandler: |
| 2666 | """Handle errors raised when executing an operation.""" |
| 2667 | |
| 2668 | __slots__ = ( |
| 2669 | "client", |
| 2670 | "server_address", |
| 2671 | "session", |
| 2672 | "max_wire_version", |
| 2673 | "sock_generation", |
| 2674 | "completed_handshake", |
| 2675 | "service_id", |
| 2676 | "handled", |
| 2677 | ) |
| 2678 | |
| 2679 | def __init__( |
| 2680 | self, |
| 2681 | client: MongoClient, # type: ignore[type-arg] |
| 2682 | server: Server, |
| 2683 | session: Optional[ClientSession], |
| 2684 | ): |
| 2685 | if not isinstance(client, MongoClient): |
| 2686 | # This is for compatibility with mocked and subclassed types, such as in Motor. |
| 2687 | if not any(cls.__name__ == "MongoClient" for cls in type(client).__mro__): |
| 2688 | raise TypeError(f"MongoClient required but given {type(client).__name__}") |
| 2689 | |
| 2690 | self.client = client |
| 2691 | self.server_address = server.description.address |
| 2692 | self.session = session |
| 2693 | self.max_wire_version = common.MIN_WIRE_VERSION |
| 2694 | # XXX: When get_socket fails, this generation could be out of date: |
| 2695 | # "Note that when a network error occurs before the handshake |
| 2696 | # completes then the error's generation number is the generation |
| 2697 | # of the pool at the time the connection attempt was started." |
| 2698 | self.sock_generation = server.pool.gen.get_overall() |
| 2699 | self.completed_handshake = False |
| 2700 | self.service_id: Optional[ObjectId] = None |
| 2701 | self.handled = False |
| 2702 | |
| 2703 | def contribute_socket(self, conn: Connection, completed_handshake: bool = True) -> None: |
| 2704 | """Provide socket information to the error handler.""" |
| 2705 | self.max_wire_version = conn.max_wire_version |
| 2706 | self.sock_generation = conn.generation |
| 2707 | self.service_id = conn.service_id |
| 2708 | self.completed_handshake = completed_handshake |
| 2709 | |
| 2710 | def handle( |
| 2711 | self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException] |
| 2712 | ) -> None: |
| 2713 | if self.handled or exc_val is None: |
| 2714 | return |
| 2715 | self.handled = True |
| 2716 | if self.session: |
| 2717 | if isinstance(exc_val, ClientBulkWriteException): |
| 2718 | exc_val = exc_val.error |
| 2719 | if isinstance(exc_val, ConnectionFailure): |
| 2720 | if self.session.in_transaction: |
| 2721 | exc_val._add_error_label("TransientTransactionError") |
| 2722 | self.session._server_session.mark_dirty() |
no outgoing calls
no test coverage detected