3434from ..utils .tracing import get_timer , trace_event
3535from .error import ProtocolMinorVersionNotSupported
3636from .protocol_registry import ProtocolRegistry
37+ from ..didcomm_v2 .protocol_registry import V2ProtocolRegistry
3738
3839
3940class ProblemReportParseError (MessageParseError ):
@@ -137,6 +138,24 @@ async def handle_v2_message(
137138 ):
138139 """Handle a DIDComm V2 message."""
139140
141+ error_result = None
142+ message = None
143+
144+ try :
145+ message = await self .make_v2_message (profile , inbound_message .payload )
146+ except ProblemReportParseError :
147+ pass # avoid problem report recursion
148+ except MessageParseError as e :
149+ self .logger .error (f"Message parsing failed: { str (e )} , sending problem report" )
150+ error_result = ProblemReport (
151+ description = {
152+ "en" : str (e ),
153+ "code" : "message-parse-failure" ,
154+ }
155+ )
156+ if inbound_message .receipt .thread_id :
157+ error_result .assign_thread_id (inbound_message .receipt .thread_id )
158+
140159 # send a DCV2 Problem Report here for testing, and to punt procotol handling down
141160 # the road a bit
142161 context = RequestContext (profile )
@@ -150,18 +169,98 @@ async def handle_v2_message(
150169 )
151170
152171 context .injector .bind_instance (BaseResponder , responder )
153- error_result = V2AgentMessage (
154- message = {
155- "type" : "https://didcomm.org/report-problem/2.0/problem-report" ,
156- "body" : {
157- "comment" : "No Handlers Found" ,
158- "code" : "e.p.msg.not-found" ,
159- },
160- }
161- )
162- if inbound_message .receipt .thread_id :
163- error_result .message ["pthid" ] = inbound_message .receipt .thread_id
164- await responder .send_reply (error_result )
172+ if not message :
173+ error_result = V2AgentMessage (
174+ message = {
175+ "type" : "https://didcomm.org/report-problem/2.0/problem-report" ,
176+ "body" : {
177+ "comment" : "No Handlers Found" ,
178+ "code" : "e.p.msg.not-found" ,
179+ },
180+ }
181+ )
182+ if inbound_message .receipt .thread_id :
183+ error_result .message ["pthid" ] = inbound_message .receipt .thread_id
184+
185+ # # When processing oob attach message we supply the connection id
186+ # # associated with the inbound message
187+ # if inbound_message.connection_id:
188+ # async with self.profile.session() as session:
189+ # connection = await ConnRecord.retrieve_by_id(
190+ # session, inbound_message.connection_id
191+ # )
192+ # else:
193+ # connection_mgr = BaseConnectionManager(profile)
194+ # connection = await connection_mgr.find_inbound_connection(
195+ # inbound_message.receipt
196+ # )
197+ # del connection_mgr
198+
199+ # if connection:
200+ # inbound_message.connection_id = connection.connection_id
201+
202+ # context.connection_ready = connection and connection.is_ready
203+ # context.connection_record = connection
204+ # responder.connection_id = connection and connection.connection_id
205+
206+ if error_result :
207+ await responder .send_reply (error_result )
208+ elif context .message :
209+ context .injector .bind_instance (BaseResponder , responder )
210+
211+ handler_cls = context .message .Handler
212+ handler = handler_cls ().handle
213+ if self .collector :
214+ handler = self .collector .wrap_coro (handler , [handler .__qualname__ ])
215+ await handler (context , responder )
216+
217+ async def make_v2_message (self , profile : Profile , parsed_msg : dict ) -> BaseMessage :
218+ """Deserialize a message dict into the appropriate message instance.
219+
220+ Given a dict describing a message, this method
221+ returns an instance of the related message class.
222+
223+ Args:
224+ parsed_msg: The parsed message
225+ profile: Profile
226+
227+ Returns:
228+ An instance of the corresponding message class for this message
229+
230+ Raises:
231+ MessageParseError: If the message doesn't specify @type
232+ MessageParseError: If there is no message class registered to handle
233+ the given type
234+
235+ """
236+ if not isinstance (parsed_msg , dict ):
237+ raise MessageParseError ("Expected a JSON object" )
238+ message_type = parsed_msg .get ("type" )
239+
240+ if not message_type :
241+ raise MessageParseError ("Message does not contain 'type' parameter" )
242+
243+ registry : V2ProtocolRegistry = self .profile .inject (V2ProtocolRegistry )
244+ try :
245+ #message_cls = registry.resolve_message_class(message_type)
246+ #if isinstance(message_cls, DeferLoad):
247+ # message_cls = message_cls.resolved
248+ message_cls = V2ProtocolRegistry .protocols_matching_query (message_type )
249+ except ProtocolMinorVersionNotSupported as e :
250+ raise MessageParseError (f"Problem parsing message type. { e } " )
251+
252+ if not message_cls :
253+ raise MessageParseError (f"Unrecognized message type { message_type } " )
254+
255+ try :
256+ instance = message_cls [0 ] #message_cls.deserialize(parsed_msg)
257+ except BaseModelError as e :
258+ if "/problem-report" in message_type :
259+ raise ProblemReportParseError ("Error parsing problem report message" )
260+ raise MessageParseError (f"Error deserializing message: { e } " ) from e
261+
262+ return instance
263+
165264
166265 async def handle_v1_message (
167266 self ,
0 commit comments