1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【gRPC】 Unknown field name '' in initialization map entryエラーの発生原因と対処法

Posted at

gRPC(ruby)で以下のようなエラーが発生した場合の原因と対処法。

"error": "13 INTERNAL: Unknown field name '文字列' in initialization map entry.\n\n/app/grpc/lib/helpers/article_helper.rb:222:

初期化時に指定した名前のフィールドが存在しないというエラー。

丁寧に該当するエラーが発生したファイル名と行を教えてくれている。


## field nameとは? フィールド名とはprotocol buffers(.protoファイル)で定義した要素を指している。
.proto
message <メーセージ名> {
  <型> <フィールド名> = <フィールド番号>;
  .
  .
  .
}

エラーは.protoファイルに渡したフィールド名が存在しないことを伝えている。


## 発生状況と対処法

.rbに記述したサーバーコードで.protoファイルのクラス生成時に、存在しないフィールド名を渡したため。

エラーが発生したコード
PJ::Model::ArticleItem.new("rowspan")`

名前空間PJ::ModelのクラスArticleItemのインスタンスを作成し、引数に"rowspan"を渡している。

この記述と.protoの対応は以下となる。

  • ArticleItemがmessage名
  • 引数で渡したrowspanがフィールド名

.protoファイルの指定したmessageで指定したフィールドを設定していないために発生したエラー。


.protoファイル
//名前空間の設定
package pj.model;

message ArticleItem {
  ArticleItemTdTh td_th = 1;
}

message ArticleItemTdTh {
  int32 rowspan = 1;
  int32 colspan = 2;
}

該当するメッセージ名ArticleItemで使えるフィールド名はtd_th

対処法

引数で渡すフィールド名をtd_thに変更すればいい。

PJ::Model::ArticleItem.new("td_th")

以上でエラーが解消する。


## (補足)発生状況詳細 実際のコードはもう少し複雑なので、以下は参考。
.rb
## エラーが発生した処理
def convert_article_item(article_item:)
    
    #変数item_typeの宣言
    item_type = article_item['item_type']

    ##rowspan & colspanの設定
    #item_typeが"TYPE_TD"かつ、値rowspanとcolspanが存在するなら
    #変数rowspanとcolspanに代入
    if item_type == "TYPE_TD" and (rowspan = article_item['rowspan'] and colspan = article_item['colspan'])

      #convert_item_td_thメソッドにキーワード引数で変数rowspanとcolspanを渡す。
      #実行結果を article_item_paramsに代入
      article_item_params['td_th'] = convert_item_td_th(rowspan: rowspan, colspan: colspan) 
    
    #item_typeの条件は複数存在
    elsif item_type = ....
    .
    .
    .
    
    end
    
   #メッセージ名ArticleItemに変数article_item_paramsに代入した値をフィールド名として渡す
   PJ::Model::ArticleItem.new(article_item_params)
end


def convert_item_td_th(rowspan:, colspan:)
    td_th_params = {}
    td_th_params['rowspan'] = rowspan if rowspan.present?
    td_th_params['colspan'] = colspan if colspan.present?
    
    PJ::Model::ArticleItemTdTh.new(td_th_params)
end

item_typeに複数のパターンが存在する。

TYPE_TDかつ、article_item['rowspan'], article_item['colspan']が存在する時に、

convert_item_td_thメソッドを実行する。
キーワード引数としてrowspan, colspanを渡す。

td_th_paramas = {'rowspan' = rowspan, 'colspan' = colspan}をフィールド名として、メッセージArticleItemTdThに渡す。

.proto
package pj.model;

message ArticleItem {
  //列挙型でTYPE_の種類だけフィールドを用意
  enum Type {
    TYPE_INVALID = 0;
    TYPE_DIV = 1;
    TYPE_CODE = 2;
    TYPE_TYPOGRAPHY = 9;
    TYPE_IMAGE = 10;
    TYPE_HTML = 11;
    TYPE_TEXT = 12;
    TYPE_LI = 14;
    TYPE_DT = 15;
    TYPE_DD = 16;
    TYPE_UL = 17;
    TYPE_OL = 18;
    TYPE_DL = 19;
    TYPE_TABLE = 20;
    TYPE_TR = 21;
    TYPE_TH = 22;
    TYPE_TD = 23;
    TYPE_TOC = 24; 
  }

  //該当するTYPE_をフィールドtypeに渡す。
  Type type = 3;

  //今回使っているのはここのArticleItemTdTh
  oneof type_details {
    ItemTypography typography = 10;
    ArticleItemImage image = 11;
    ArticleItemCode code = 12;
    ArticleItemHtml html = 13;
    ArticleItemToc toc = 14;
    ArticleItemTable table = 16;
    ArticleItemTdTh td_th = 17;
  }
}

//ArticleItemTdThの型とフィールド
message ArticleItemTdTh {
  int32 rowspan = 1;
  int32 colspan = 2;
}

ArticleItemTdTh.new('td_th')が、OneofArticleItemTdTh td_thに対応する。

ArticleItemTdThはmessageの中で他のmessageを型として呼び出せる仕様を利用している。

td_th = {rowspan:数値 , colspan:数値}の形のデータが受け渡される。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?