(
self,
dctx: DispatchContext[TransportContext],
method: str,
params: Mapping[str, Any] | None,
)
| 292 | return result |
| 293 | |
| 294 | async def _on_notify( |
| 295 | self, |
| 296 | dctx: DispatchContext[TransportContext], |
| 297 | method: str, |
| 298 | params: Mapping[str, Any] | None, |
| 299 | ) -> None: |
| 300 | meta = _extract_meta(params) |
| 301 | version = self.connection.protocol_version |
| 302 | ctx = self._make_context(dctx, method, params, meta, version) |
| 303 | |
| 304 | async def _inner(ctx: ServerRequestContext[LifespanT, Any]) -> None: |
| 305 | method, params = ctx.method, ctx.params |
| 306 | if method in _methods.SPEC_CLIENT_NOTIFICATION_METHODS: |
| 307 | try: |
| 308 | _methods.validate_client_notification(method, version, params) |
| 309 | except KeyError: |
| 310 | logger.debug("dropped %r: not defined at %s", method, version) |
| 311 | return |
| 312 | except ValidationError: |
| 313 | logger.warning("dropped %r: malformed params", method) |
| 314 | return |
| 315 | if method == "notifications/initialized": |
| 316 | # Surface validation above already rejected a malformed body, so |
| 317 | # commit; fall through so a registered handler observes an |
| 318 | # initialized connection. |
| 319 | self.connection.initialized.set() |
| 320 | elif not self.connection.initialize_accepted: |
| 321 | logger.debug("dropped %s: received before initialization", method) |
| 322 | return |
| 323 | entry = self.server.get_notification_handler(method) |
| 324 | if entry is None: |
| 325 | logger.debug("no handler for notification %s", method) |
| 326 | return |
| 327 | # Same absent-params contract as requests. |
| 328 | try: |
| 329 | typed_params = entry.params_type.model_validate({} if params is None else params, by_name=False) |
| 330 | except ValidationError: |
| 331 | logger.warning("dropped %r: malformed params", method) |
| 332 | return |
| 333 | await entry.handler(ctx, typed_params) |
| 334 | |
| 335 | call = self._compose_server_middleware(_inner) |
| 336 | try: |
| 337 | await call(ctx) |
| 338 | except Exception: |
| 339 | # A crashing handler must not cancel the dispatcher's task group; |
| 340 | # middleware saw the raise out of call_next() first. |
| 341 | logger.exception("notification handler for %r raised", method) |
| 342 | |
| 343 | def _compose_server_middleware(self, inner: CallNext) -> CallNext: |
| 344 | """Wrap `inner` in `Server.middleware`, outermost-first. |
no test coverage detected