Errors
API reference for validation, registration, dispatch, and service-resolution errors.
Most validation and dispatch errors inherit from PyMediateError. Service resolution uses the
separate ServiceNotFoundError, which inherits from KeyError — a provider is a type-keyed
mapping, so a missing service is a missing key. Subscriber failures from publish() use Python's
built-in exception groups.
PyMediateError
from pymediate import PyMediateError
class PyMediateError(Exception):
def __init__(
self,
message: str,
docs_path: str | None = None,
): ...docs_path is stored on the exception. When present, PyMediate appends the corresponding
documentation URL to the exception message.
Definition-time errors
Handler classes are validated and registered when Python defines them, usually while importing a module. These errors indicate a class declaration that does not meet the handler contract.
InvalidHandlerSignatureError
class InvalidHandlerSignatureError(PyMediateError):
def __init__(self, handler_type: type, issue: str): ...Raised when a request, stream, or notification handler's __call__ has the wrong number of parameters,
annotations, or synchronous/asynchronous form. Stream handlers also raise it when __call__ is not
the required generator form. The handler_type and issue attributes describe the failed
declaration.
InvalidRequestTypeError
class InvalidRequestTypeError(PyMediateError):
def __init__(self, request_type: type): ...Raised when RequestHandler[...] is parameterized with a type that has no recorded
Request[ResponseT] relationship. The rejected type is available as request_type.
InvalidNotificationTypeError
class InvalidNotificationTypeError(PyMediateError):
def __init__(self, notification_type: type): ...Raised when NotificationHandler[...] is parameterized with a type that is not an Notification subclass. The
rejected type is available as notification_type.
InvalidStreamRequestTypeError
class InvalidStreamRequestTypeError(PyMediateError):
def __init__(self, stream_request_type: type): ...Raised when StreamRequestHandler[...] is parameterized with a type that is not a parameterized
StreamRequest subclass. The rejected type is available as stream_request_type.
ResponseTypeMismatchError
class ResponseTypeMismatchError(PyMediateError):
def __init__(
self,
handler_type: type,
expected_type: type,
actual_type: type,
): ...Raised when a request handler's return annotation differs from the response type declared by its
request. It compares annotations while defining the class; PyMediate does not inspect the returned
value later. The arguments are stored as handler_type, expected_type, and actual_type.
HandlerAlreadyRegisteredError
class HandlerAlreadyRegisteredError(PyMediateError):
def __init__(
self,
request_type: type,
existing_handler: type,
new_handler: type,
existing_location: str | None = None,
): ...Raised when a second request handler or stream handler is defined for a request type already in the process-wide registry. Its attributes retain the request type, both handler classes, and the first registration location when available. Notification handlers do not use this one-handler limit.
Construction-time errors
ServiceAlreadyRegisteredError
class ServiceAlreadyRegisteredError(PyMediateError):
def __init__(self, service_type: type): ...Raised by Services(...) when two instances passed to one construction share a concrete type.
A collection holds one instance per exact type, so only the first could ever be resolved — a
repeat is a wiring mistake rather than a preference. The repeated type is stored as
service_type. Use left | right to replace a service deliberately; the right operand wins and
a shared type is not an error there.
InvalidPipelineBehaviorsError
class InvalidPipelineBehaviorsError(PyMediateError):
def __init__(self, entry: object, issue: str): ...Mediator(services, behaviors=[...]) validates the behaviors sequence once, when the mediator is
constructed. Raised when an entry is not a PipelineBehavior subclass of the mediator's variant,
is not registered with services, or is listed more than once. The offending entry and a
description of the failed check are stored as entry and issue.
Dispatch-time errors
HandlerNotFoundError
class HandlerNotFoundError(PyMediateError):
def __init__(
self,
request_type: type,
available_handlers: list[type] | None = None,
): ...Mediator.send() and Mediator.stream() raise this error when the exact request class has no
registered handler class. The attributes are request_type and available_handlers. A missing
handler instance is instead a service-resolution error.
ServiceNotFoundError
class ServiceNotFoundError(KeyError):
def __init__(
self,
service_type: type,
available_types: list[type],
) -> None: ...ServiceProvider.__getitem__ raises this error when no instance is registered for the exact requested
type. During mediator dispatch, that can occur while resolving a request handler, stream handler,
or notification handler. The arguments are stored as service_type and available_types.
It subclasses KeyError, mirroring the subscript that raises it (provider[service_type]), so a
missing service can be caught with except KeyError. str(error) still renders the full multi-line
message rather than KeyError's repr-wrapped form.
Because ServiceNotFoundError is not a PyMediateError, catching PyMediateError alone does not
catch all mediator configuration failures.
Other propagated failures
send()lets handler and pipeline-behavior exceptions propagate unchanged.stream()lets generator-body exceptions propagate during iteration.- Asynchronous
publish()aggregates ordinary subscriber failures in anExceptionGroup. Other collectedBaseExceptionvalues produce aBaseExceptionGroup;KeyboardInterruptandSystemExitpropagate directly and can cancel unfinished subscribers. - Synchronous
publish()aggregates ordinary subscriber exceptions in anExceptionGroup. A directBaseExceptionthat is not anExceptionstops delivery and propagates immediately.
See also
- Error handling — application boundaries and domain errors
- Troubleshooting — likely causes and corrections
- Mediator — when dispatch errors are raised