4141import pulsar
4242from pulsar import _check_type
4343
44- class PulsarException (BaseException ):
44+ class PulsarException (Exception ):
4545 """
4646 The exception that wraps the Pulsar error code
4747 """
4848
49- def __init__ (self , result : pulsar .Result ) -> None :
49+ def __init__ (self , result : pulsar .Result , msg : str | None = None ) -> None :
5050 """
5151 Create the Pulsar exception.
5252
5353 Parameters
5454 ----------
5555 result: pulsar.Result
5656 The error code of the underlying Pulsar APIs.
57+ msg: str | None
58+ An optional error message providing more details.
5759 """
5860 self ._result = result
61+ self ._msg = msg
5962
6063 def error (self ) -> pulsar .Result :
6164 """
@@ -67,6 +70,8 @@ def __str__(self):
6770 """
6871 Convert the exception to string.
6972 """
73+ if self ._msg :
74+ return f'{ self ._result .value } { self ._result .name } : { self ._msg } '
7075 return f'{ self ._result .value } { self ._result .name } '
7176
7277class Producer :
@@ -591,8 +596,8 @@ def underlying_router(msg: _pulsar.Message, num_partitions: int) -> int:
591596 return message_router (pulsar .Message ._wrap (msg ), num_partitions )
592597 conf .message_router (underlying_router )
593598
594- self ._client .create_producer_async (
595- topic , conf , functools .partial (_set_future , future )
599+ self ._client .create_producer_async_v2 (
600+ topic , conf , functools .partial (_set_future_v2 , future )
596601 )
597602 return Producer (await future , schema )
598603
@@ -751,28 +756,23 @@ async def subscribe(self, topic: Union[str, List[str]],
751756
752757 if isinstance (topic , str ):
753758 if is_pattern_topic :
754- self ._client .subscribe_async_pattern (
755- topic , subscription_name , conf ,
756- functools .partial (_set_future , future )
757- )
759+ topics = _pulsar .TopicRegex (topic )
758760 else :
759- self ._client .subscribe_async (
760- topic , subscription_name , conf ,
761- functools .partial (_set_future , future )
762- )
761+ topics = topic
763762 elif isinstance (topic , list ):
764763 if is_pattern_topic :
765764 raise ValueError (
766765 "Argument 'topic' must be a string when "
767766 "'is_pattern_topic' is True; lists of topics do not "
768767 "support pattern subscriptions"
769768 )
770- self ._client .subscribe_async_topics (
771- topic , subscription_name , conf ,
772- functools .partial (_set_future , future )
773- )
769+ topics = topic
774770 else :
775771 raise ValueError ( "Argument 'topic' is expected to be of type 'str' or 'list'" )
772+ self ._client .subscribe_async_v2 (
773+ topics , subscription_name , conf ,
774+ functools .partial (_set_future_v2 , future )
775+ )
776776
777777 schema .attach_client (self ._client )
778778 return Consumer (await future , schema )
@@ -835,3 +835,14 @@ def complete():
835835 else :
836836 future .set_exception (PulsarException (result ))
837837 future .get_loop ().call_soon_threadsafe (complete )
838+
839+ def _set_future_v2 (future : asyncio .Future , value : Any ):
840+ def callback ():
841+ if future .done ():
842+ return
843+ if isinstance (value , _pulsar .Error ):
844+ exc = PulsarException (value .error , value .message )
845+ future .get_loop ().call_soon_threadsafe (future .set_exception , exc )
846+ else :
847+ future .get_loop ().call_soon_threadsafe (future .set_result , value )
848+ future .get_loop ().call_soon_threadsafe (callback )
0 commit comments