anchor.diff:                  errorMessage,
                   null,
                 ));
  -          logError(error.toString());
  -          if (stackTrace != null) {
  -            logError(stackTrace.toString());
  -          }
  +          logException(errorMessage, error, stackTrace);
           }
         });
       }, onError: error);
     }
   
  -  void logError(String message) {
  +  /// Logs the error on the client using window/logMessage.
  +  void logErrorToClient(String message) {
       channel.sendNotification(new NotificationMessage(
         Method.window_logMessage,
         new LogMessageParams(MessageType.Error, message),
  
positive.code:   }
  
    void sendServerErrorNotification(String message, exception, stackTrace) {
      final fullError = new StringBuffer();
  
      fullError.writeln(exception == null ? message : '$message: $exception');
  
      // Show message (without stack) to the user.
      showError(fullError.toString());
  
      if (stackTrace != null) {
        fullError.writeln(stackTrace.toString());
      }
      // Log the full message since showMessage above may be truncated or formatted
      // badly (eg. VS Code takes the newlines out).
      logError(fullError.toString());
  
      // remember the last few exceptions
      if (exception is CaughtException) {
        stackTrace ??= exception.stackTrace;
      }
      exceptions.add(new ServerException(
        message,
        exception,
  
negative.code:           new ResponseMessage(message.id, null, error, jsonRpcVersion));
        // Since the LSP client might not show the failed requests to the user,
        // also ensure the error is logged to the client.
        logErrorToClient(error.message);
      } else if (message is ResponseMessage) {
        // For bad response messages where we can't respond with an error, send it as
        // show instead of log.
  