Skip to content

エラーリファレンス

wirespec のエラーは 2 種類あります。生成された C 関数が返すランタイムエラーコードと、コンパイル時に出力されるコンパイラエラーです。


ランタイムエラーコード

生成されたパース/シリアライズ関数はすべて wirespec_result_t を返します:

コード意味
WIRESPEC_OK0成功
WIRESPEC_ERR_SHORT_BUFFER1バッファの残りバイトが不足(パースまたはシリアライズ)
WIRESPEC_ERR_INVALID_TAG2frame / capsule のどのパターンにもマッチしないタグ値
WIRESPEC_ERR_CONSTRAINT3require 式が false
WIRESPEC_ERR_OVERFLOW4整数オーバーフロー(VarInt 値の範囲超過、長さ値が SIZE_MAX 超過など)
WIRESPEC_ERR_INVALID_STATE5ステートマシンに該当する遷移がないイベント
WIRESPEC_ERR_TRAILING_DATA6within EXPR スコープが完全に消費されなかった
WIRESPEC_ERR_NONCANONICAL7@strict 型が非正規(非最小長)エンコーディング
WIRESPEC_ERR_UNSUPPORTED8生成コードが未対応の機能
WIRESPEC_ERR_CAPACITY9配列要素数がキャパシティ超過(WIRESPEC_MAX_ARRAY_ELEMENTS または @max_len
WIRESPEC_ERR_CHECKSUM10チェックサム検証失敗
WIRESPEC_ERR_SCOPE_UNDERFLOW11サブカーソルのアンダーフロー — 内部スコープ境界の違反
WIRESPEC_ERR_ARRAY_OVERFLOW12パース中に配列インデックスが範囲外

wirespec_runtime.h での定義:

c
typedef enum {
    WIRESPEC_OK                  = 0,
    WIRESPEC_ERR_SHORT_BUFFER    = 1,
    WIRESPEC_ERR_INVALID_TAG     = 2,
    WIRESPEC_ERR_CONSTRAINT      = 3,
    WIRESPEC_ERR_OVERFLOW        = 4,
    WIRESPEC_ERR_INVALID_STATE   = 5,
    WIRESPEC_ERR_TRAILING_DATA   = 6,
    WIRESPEC_ERR_NONCANONICAL    = 7,
    WIRESPEC_ERR_UNSUPPORTED     = 8,
    WIRESPEC_ERR_CAPACITY        = 9,
    WIRESPEC_ERR_CHECKSUM        = 10,
    WIRESPEC_ERR_SCOPE_UNDERFLOW = 11,
    WIRESPEC_ERR_ARRAY_OVERFLOW  = 12,
} wirespec_result_t;

エラー処理パターン

c
wirespec_result_t rc = quic_frames_quic_frame_parse(buf, len, &frame, &consumed);
switch (rc) {
    case WIRESPEC_OK:
        break;
    case WIRESPEC_ERR_SHORT_BUFFER:
        /* データ不足 — 追加バイトを待つか、入力の切断を報告 */
        break;
    case WIRESPEC_ERR_INVALID_TAG:
        /* 不明なフレームタイプ — 破棄またはログ */
        break;
    case WIRESPEC_ERR_CONSTRAINT:
        /* プロトコル制約違反 — 接続を閉じる */
        break;
    case WIRESPEC_ERR_CHECKSUM:
        /* パケット破損 — 破棄 */
        break;
    default:
        /* 想定外のエラー */
        break;
}

各エラーコードの補足

WIRESPEC_ERR_SHORT_BUFFER — インクリメンタルパースで最もよく発生します。リングバッファにデータを蓄積している場合は、このエラーが返ったらデータを追加して再試行してください。

WIRESPEC_ERR_INVALID_TAGframe / capsule_ ワイルドカードブランチがない場合のみ返ります。_ => Unknown { data: bytes[remaining] } を追加すれば、未知のタグはエラーではなくキャプチャされます。

WIRESPEC_ERR_NONCANONICAL@strict 付きの型でのみ返ります。@strict なしなら、有効な値にデコードできるエンコーディングはすべて受け付けます。

WIRESPEC_ERR_TRAILING_DATAwithin EXPR スコープで、宣言された長さ分のバイトが完全に消費されなかったことを示します。不正なパケットか、フィールドが追加された新プロトコルバージョンが原因です。

WIRESPEC_ERR_UNSUPPORTED — 入力が生成コードで未対応の機能やバリアントを要求していることを示します。

WIRESPEC_ERR_CAPACITY — プロトコルエラーではなく、生成コードの静的配列サイズが足りないことを意味します。-DWIRESPEC_MAX_ARRAY_ELEMENTS=N またはフィールドの @max_len(N) でキャパシティを増やしてください。

WIRESPEC_ERR_SCOPE_UNDERFLOW — サブカーソルのスコープ境界が破られた内部エラーです。通常、プロトコル定義のバグまたは生成コードの内部エラーを示します。

WIRESPEC_ERR_ARRAY_OVERFLOW — パース中に配列インデックスが範囲外になったことを示します。生成コード内の安全チェックです。


コンパイラエラー

wirespec コンパイラは、ソースファイルパス、行・列番号、ソース行の抜粋、^^^^^ ポインター、コンテキスト情報、ヒントテキストを含む診断を出力します。

表示形式

error: undefined type 'Varnt'
 --> file.wspec:2:7
  |
2 |     x: Varnt,
  |        ^^^^^
  = in packet 'Foo'
  hint: did you mean 'VarInt'?
フィールド説明
error:エラーメッセージ
-->ファイルパス:行:列
ソース行エラー箇所のソーステキスト
^^^^^問題のトークンを指す
= in ...コンテキスト — 包含する定義
hint:ヒント(類似名の提案など)

よくあるコンパイルエラー

未定義の型・フィールド:

error: undefined type 'AckRng'
 --> examples/quic/frames.wspec:12:15
  |
12 |     gap: AckRng,
  |          ^^^^^^
  = in packet 'AckRange'
  hint: did you mean 'AckRange'?

型名のタイポか import の不足。レーベンシュタイン距離で最も近い名前を提案します。

前方参照:

error: field 'length' is used before it is declared
 --> examples/quic/frames.wspec:8:28

フィールドは宣言より前のフィールドのみ参照可能です。同スコープで後に宣言されたフィールドは参照できません。

長さ/カウントに非整数型を使用:

error: 'bytes[length: x]' requires an integer-like type; got 'bool'

bytes[length: EXPR]bytes[length_or_remaining: EXPR][T; EXPR]within EXPR の式は整数類似型(u8u16u32u64VarInt など)でなければなりません。

remaining / fill がスコープ末尾でない:

error: 'bytes[remaining]' must be the last wire field in its scope
 --> examples/quic/frames.wspec:22:5

bytes[remaining][T; fill] はスコープの残りバイトをすべて消費します。後続にワイヤフィールドは置けません(letrequire は可)。

循環インポート:

error: circular import detected: a -> b -> c -> a

wirespec は循環インポートに非対応です。共有型を共通モジュールに切り出してください。

ステートマシン action でのフィールド未初期化:

error: field 'dst.challenge' has no default value and is not assigned in action
 --> examples/mpquic/path.wspec:18:5

デフォルト値のない遷移先フィールドは action ブロック内で必ず代入が必要です。= default_value 付きのフィールドは省略可能。

予約識別子の使用:

error: 'remaining' is a reserved keyword and cannot be used as a field name

boolnullfillremainingin_stateallchild_state_changedsrcdst は予約済みで、ユーザー定義名に使えません。

@checksum の重複:

error: at most one @checksum annotation is allowed per packet/frame branch

@checksum のフィールド型不一致:

error: @checksum(internet) requires field type u16; got u32

類似名の提案

未定義の名前が使われると、コンパイラはスコープ内の全名前とのレーベンシュタイン距離を計算し、近いものがあれば hint: ヒントで提案します。型名、フィールド名、インポートパスが対象です。

コンテキストスタック

ネストした構造(frame ブランチ内、capsule ペイロード内など)でのエラーには、包含する定義を示すコンテキスト情報が付きます:

error: type mismatch ...
 --> examples/quic/frames.wspec:45:20
  |
  = in field 'data' in frame branch 'Stream'
  = in frame 'QuicFrame'