@@ -230,13 +230,13 @@ public final class JSONRPCConnection: Connection {
230
230
}
231
231
}
232
232
233
- /// Send a notification to the client that informs the user about a message decoding error and tells them to file an
234
- /// issue.
233
+ /// Send a notification to the client that informs the user about a message encoding or decoding error and asks them
234
+ /// to file an issue.
235
235
///
236
236
/// `message` describes what has gone wrong to the user.
237
237
///
238
238
/// - Important: Must be called on `queue`
239
- private func sendMessageDecodingErrorNotificationToClient ( message: String ) {
239
+ private func sendMessageCodingErrorNotificationToClient ( message: String ) {
240
240
dispatchPrecondition ( condition: . onQueue( queue) )
241
241
let showMessage = ShowMessageNotification (
242
242
type: . error,
@@ -302,7 +302,7 @@ public final class JSONRPCConnection: Connection {
302
302
// That way the user at least knows that something is going wrong even if the client never gets a response
303
303
// for the request.
304
304
logger. fault ( " Ignoring request because we failed to decode the request and don't have a request ID " )
305
- sendMessageDecodingErrorNotificationToClient ( message: " sourcekit-lsp failed to decode a request " )
305
+ sendMessageCodingErrorNotificationToClient ( message: " sourcekit-lsp failed to decode a request " )
306
306
return nil
307
307
case . response:
308
308
if let id = error. id {
@@ -338,19 +338,19 @@ public final class JSONRPCConnection: Connection {
338
338
// `textDocument/didChange` will result in an out-of-sync state between the editor and sourcekit-lsp.
339
339
// Warn the user about the error.
340
340
logger. fault ( " Ignoring notification that may cause corrupted behavior " )
341
- sendMessageDecodingErrorNotificationToClient ( message: " sourcekit-lsp failed to decode a notification " )
341
+ sendMessageCodingErrorNotificationToClient ( message: " sourcekit-lsp failed to decode a notification " )
342
342
return nil
343
343
case . unknown:
344
344
// We don't know what has gone wrong. This could be any level of badness. Inform the user about it.
345
345
logger. fault ( " Ignoring unknown message " )
346
- sendMessageDecodingErrorNotificationToClient ( message: " sourcekit-lsp failed to decode a message " )
346
+ sendMessageCodingErrorNotificationToClient ( message: " sourcekit-lsp failed to decode a message " )
347
347
return nil
348
348
}
349
349
} catch {
350
350
// We don't know what has gone wrong. This could be any level of badness. Inform the user about it and ignore the
351
351
// message.
352
352
logger. fault ( " Ignoring unknown message " )
353
- sendMessageDecodingErrorNotificationToClient ( message: " sourcekit-lsp failed to decode an unknown message " )
353
+ sendMessageCodingErrorNotificationToClient ( message: " sourcekit-lsp failed to decode an unknown message " )
354
354
return nil
355
355
}
356
356
}
@@ -391,7 +391,7 @@ public final class JSONRPCConnection: Connection {
391
391
// We failed to parse the message header. There isn't really much we can do to recover because we lost our
392
392
// anchor in the stream where new messages start. Crashing and letting ourselves be restarted by the client is
393
393
// probably the best option.
394
- sendMessageDecodingErrorNotificationToClient ( message: " Failed to find next message in connection to editor " )
394
+ sendMessageCodingErrorNotificationToClient ( message: " Failed to find next message in connection to editor " )
395
395
fatalError ( " fatal error encountered while splitting JSON RPC messages \( error) " )
396
396
}
397
397
@@ -481,8 +481,40 @@ public final class JSONRPCConnection: Connection {
481
481
do {
482
482
data = try encoder. encode ( message)
483
483
} catch {
484
- // FIXME: attempt recovery?
485
- fatalError ( " unexpected error while encoding response: \( error) " )
484
+ logger. fault ( " Failed to encode message: \( error. forLogging) " )
485
+ logger. fault ( " Malformed message: \( String ( describing: message) ) " )
486
+ switch message {
487
+ case . notification( _) :
488
+ // We want to send a notification to the editor but failed to encode it. Since dropping the notification might
489
+ // result in getting out-of-sync state-wise with the editor (eg. for work progress notifications), inform the
490
+ // user about it.
491
+ sendMessageCodingErrorNotificationToClient (
492
+ message: " sourcekit-lsp failed to encode a notification to the editor "
493
+ )
494
+ return
495
+ case . request( _, _) :
496
+ // We want to send a notification to the editor but failed to encode it. We don't know the `reply` handle for
497
+ // the request at this point so we can't synthesize an errorResponse for the request. This means that the
498
+ // request will never receive a reply. Inform the user about it.
499
+ sendMessageCodingErrorNotificationToClient (
500
+ message: " sourcekit-lsp failed to encode a request to the editor "
501
+ )
502
+ return
503
+ case . response( _, _) :
504
+ // The editor sent a request to sourcekit-lsp, which failed but we can't serialize the result back to the
505
+ // client. This means that the request will never receive a reply. Inform the user about it and accept that
506
+ // we'll never send a reply.
507
+ sendMessageCodingErrorNotificationToClient (
508
+ message: " sourcekit-lsp failed to encode a response to the editor "
509
+ )
510
+ return
511
+ case . errorResponse( _, _) :
512
+ // Same as `.response`. Has an optional `id`, so can't share the case.
513
+ sendMessageCodingErrorNotificationToClient (
514
+ message: " sourcekit-lsp failed to encode an error response to the editor "
515
+ )
516
+ return
517
+ }
486
518
}
487
519
488
520
var dispatchData = DispatchData . empty
0 commit comments