@@ -9,21 +9,29 @@ import { Lifecycle, scoped } from 'tsyringe'
9
9
10
10
import { AriesFrameworkError } from '../error'
11
11
import { ConnectionService } from '../modules/connections/services/ConnectionService'
12
+ import { ProblemReportError , ProblemReportMessage } from '../modules/problem-reports'
12
13
import { JsonTransformer } from '../utils/JsonTransformer'
13
14
import { MessageValidator } from '../utils/MessageValidator'
14
15
import { replaceLegacyDidSovPrefixOnMessage } from '../utils/messageType'
15
16
17
+ import { CommonMessageType } from './../modules/common/messages/CommonMessageType'
16
18
import { AgentConfig } from './AgentConfig'
17
19
import { Dispatcher } from './Dispatcher'
18
20
import { EnvelopeService } from './EnvelopeService'
21
+ import { MessageSender } from './MessageSender'
19
22
import { TransportService } from './TransportService'
23
+ import { createOutboundMessage } from './helpers'
20
24
import { InboundMessageContext } from './models/InboundMessageContext'
21
25
26
+ export enum ProblemReportReason {
27
+ MessageParseFailure = 'message-parse-failure' ,
28
+ }
22
29
@scoped ( Lifecycle . ContainerScoped )
23
30
export class MessageReceiver {
24
31
private config : AgentConfig
25
32
private envelopeService : EnvelopeService
26
33
private transportService : TransportService
34
+ private messageSender : MessageSender
27
35
private connectionService : ConnectionService
28
36
private dispatcher : Dispatcher
29
37
private logger : Logger
@@ -33,12 +41,14 @@ export class MessageReceiver {
33
41
config : AgentConfig ,
34
42
envelopeService : EnvelopeService ,
35
43
transportService : TransportService ,
44
+ messageSender : MessageSender ,
36
45
connectionService : ConnectionService ,
37
46
dispatcher : Dispatcher
38
47
) {
39
48
this . config = config
40
49
this . envelopeService = envelopeService
41
50
this . transportService = transportService
51
+ this . messageSender = messageSender
42
52
this . connectionService = connectionService
43
53
this . dispatcher = dispatcher
44
54
this . logger = this . config . logger
@@ -84,15 +94,12 @@ export class MessageReceiver {
84
94
unpackedMessage . message
85
95
)
86
96
87
- const message = await this . transformMessage ( unpackedMessage )
97
+ let message : AgentMessage | null = null
88
98
try {
89
- await MessageValidator . validate ( message )
99
+ message = await this . transformMessage ( unpackedMessage )
100
+ await this . validateMessage ( message )
90
101
} catch ( error ) {
91
- this . logger . error ( `Error validating message ${ message . type } ` , {
92
- errors : error ,
93
- message : message . toJSON ( ) ,
94
- } )
95
-
102
+ if ( connection ) await this . sendProblemReportMessage ( error . message , connection , unpackedMessage )
96
103
throw error
97
104
}
98
105
@@ -174,12 +181,61 @@ export class MessageReceiver {
174
181
const MessageClass = this . dispatcher . getMessageClassForType ( messageType )
175
182
176
183
if ( ! MessageClass ) {
177
- throw new AriesFrameworkError ( `No message class found for message type "${ messageType } "` )
184
+ throw new ProblemReportError ( `No message class found for message type "${ messageType } "` , {
185
+ problemCode : ProblemReportReason . MessageParseFailure ,
186
+ } )
178
187
}
179
188
180
189
// Cast the plain JSON object to specific instance of Message extended from AgentMessage
181
190
const message = JsonTransformer . fromJSON ( unpackedMessage . message , MessageClass )
182
191
183
192
return message
184
193
}
194
+
195
+ /**
196
+ * Validate an AgentMessage instance.
197
+ * @param message agent message to validate
198
+ */
199
+ private async validateMessage ( message : AgentMessage ) {
200
+ try {
201
+ await MessageValidator . validate ( message )
202
+ } catch ( error ) {
203
+ this . logger . error ( `Error validating message ${ message . type } ` , {
204
+ errors : error ,
205
+ message : message . toJSON ( ) ,
206
+ } )
207
+ throw new ProblemReportError ( `Error validating message ${ message . type } ` , {
208
+ problemCode : ProblemReportReason . MessageParseFailure ,
209
+ } )
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Send the problem report message (https://didcomm.org/notification/1.0/problem-report) to the recipient.
215
+ * @param message error message to send
216
+ * @param connection connection to send the message to
217
+ * @param unpackedMessage received unpackedMessage
218
+ */
219
+ private async sendProblemReportMessage (
220
+ message : string ,
221
+ connection : ConnectionRecord ,
222
+ unpackedMessage : UnpackedMessageContext
223
+ ) {
224
+ if ( unpackedMessage . message [ '@type' ] === CommonMessageType . ProblemReport ) {
225
+ throw new AriesFrameworkError ( message )
226
+ }
227
+ const problemReportMessage = new ProblemReportMessage ( {
228
+ description : {
229
+ en : message ,
230
+ code : ProblemReportReason . MessageParseFailure ,
231
+ } ,
232
+ } )
233
+ problemReportMessage . setThread ( {
234
+ threadId : unpackedMessage . message [ '@id' ] ,
235
+ } )
236
+ const outboundMessage = createOutboundMessage ( connection , problemReportMessage )
237
+ if ( outboundMessage ) {
238
+ await this . messageSender . sendMessage ( outboundMessage )
239
+ }
240
+ }
185
241
}
0 commit comments