code: func (handler *Handler) handleMessage(msg *pb.ChaincodeMessage, errc chan error) error {
  	if msg.Type == pb.ChaincodeMessage_KEEPALIVE {
  		chaincodeLogger.Debug("Sending KEEPALIVE response")
  		handler.serialSendAsync(msg, nil) // ignore errors, maybe next KEEPALIVE will work
  		return nil
  	}
  	chaincodeLogger.Debugf("[%s] Handling ChaincodeMessage of type: %s(state:%s)", shorttxid(msg.Txid), msg.Type, handler.state)
  
  	var err error
  
  	switch handler.state {
  	case ready:
  		err = handler.handleReady(msg, errc)
  	case established:
  		err = handler.handleEstablished(msg, errc)
  	case created:
  		err = handler.handleCreated(msg, errc)
  	default:
  		err = errors.Errorf("[%s] Chaincode handler cannot handle message (%s) with payload size (%d) while in state: %s", msg.Txid, msg.Type, len(msg.Payload), handler.state)
  	}
  
  	if err != nil {
  		payload := []byte(err.Error())
  		errorMsg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  		handler.serialSend(errorMsg)
  		return err
  	}
  
  	return nil
  }
docs: // handleMessage message handles loop for shim side of chaincode/peer stream.