エラーリファレンス
wirespec のエラーは 2 種類あります。生成された C 関数が返すランタイムエラーコードと、コンパイル時に出力されるコンパイラエラーです。
ランタイムエラーコード
生成されたパース/シリアライズ関数はすべて wirespec_result_t を返します:
| コード | 値 | 意味 |
|---|---|---|
WIRESPEC_OK | 0 | 成功 |
WIRESPEC_ERR_SHORT_BUFFER | 1 | バッファの残りバイトが不足(パースまたはシリアライズ) |
WIRESPEC_ERR_INVALID_TAG | 2 | frame / capsule のどのパターンにもマッチしないタグ値 |
WIRESPEC_ERR_CONSTRAINT | 3 | require 式が false |
WIRESPEC_ERR_OVERFLOW | 4 | 整数オーバーフロー(VarInt 値の範囲超過、長さ値が SIZE_MAX 超過など) |
WIRESPEC_ERR_INVALID_STATE | 5 | ステートマシンに該当する遷移がないイベント |
WIRESPEC_ERR_TRAILING_DATA | 6 | within EXPR スコープが完全に消費されなかった |
WIRESPEC_ERR_NONCANONICAL | 7 | @strict 型が非正規(非最小長)エンコーディング |
WIRESPEC_ERR_UNSUPPORTED | 8 | 生成コードが未対応の機能 |
WIRESPEC_ERR_CAPACITY | 9 | 配列要素数がキャパシティ超過(WIRESPEC_MAX_ARRAY_ELEMENTS または @max_len) |
WIRESPEC_ERR_CHECKSUM | 10 | チェックサム検証失敗 |
WIRESPEC_ERR_SCOPE_UNDERFLOW | 11 | サブカーソルのアンダーフロー — 内部スコープ境界の違反 |
WIRESPEC_ERR_ARRAY_OVERFLOW | 12 | パース中に配列インデックスが範囲外 |
wirespec_runtime.h での定義:
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;エラー処理パターン
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_TAG — frame / capsule に _ ワイルドカードブランチがない場合のみ返ります。_ => Unknown { data: bytes[remaining] } を追加すれば、未知のタグはエラーではなくキャプチャされます。
WIRESPEC_ERR_NONCANONICAL — @strict 付きの型でのみ返ります。@strict なしなら、有効な値にデコードできるエンコーディングはすべて受け付けます。
WIRESPEC_ERR_TRAILING_DATA — within 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 の式は整数類似型(u8、u16、u32、u64、VarInt など)でなければなりません。
remaining / fill がスコープ末尾でない:
error: 'bytes[remaining]' must be the last wire field in its scope
--> examples/quic/frames.wspec:22:5bytes[remaining] と [T; fill] はスコープの残りバイトをすべて消費します。後続にワイヤフィールドは置けません(let と require は可)。
循環インポート:
error: circular import detected: a -> b -> c -> awirespec は循環インポートに非対応です。共有型を共通モジュールに切り出してください。
ステートマシン 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 namebool、null、fill、remaining、in_state、all、child_state_changed、src、dst は予約済みで、ユーザー定義名に使えません。
@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'