Skip to content

tech-debt(validation) — OpenApiResponseValidator が非配列の responses[$status] エントリで未捕捉 TypeError になる #258

@wadakatu

Description

@wadakatu

背景

PR #257(issue #256ResponseBodyValidator の malformed-schema ガード)の multi-agent レビュー(/pr-review-toolkit:review-pr)で silent-failure-hunter が指摘。#256 以前から存在する既存ギャップで、#256 が追加した content / content[mediaType] / schema の非配列ガードの一階層上にあたるため、content/schema 階層に限定された #256 のスコープ外として切り出し。

現状

OpenApiResponseValidator::validate() は matched response key を解決したあと:

// src/OpenApiResponseValidator.php:190
$responseSpec = $responses[$matchedResponseKey];

validateBody() / validateHeaders() に渡す。両メソッドは引数を array 型で受ける:

private function validateBody(..., array $responseSpec, ...): ResponseBodyValidationResult
private function validateHeaders(..., array $responseSpec, ...): array

問題

spec の responses map のエントリが非配列スカラーのとき(例: responses: {"200": "oops"}、未解決 $ref がスカラーに decode された場合等)、$responseSpec がスカラーになり、validateBody() / validateHeaders()array 引数型で TypeError が発生する。

TypeError extends ErrorRuntimeException ではない)ため、validateBody() 内の catch (RuntimeException $e) boundary を素通りし、読みやすい spec エラーではなくスタックトレースだけのクラッシュになる。

これは PR #257 (#256) が content 非配列に対して追加したガードと 構造的に同一の問題RequestBodyValidatorrequestBody 自体が非配列のケースを loud な spec エラー(Malformed 'requestBody' ...)として弾いており、response 側の responses[$status] にはその対称物が無い。

既存 fixture tests/fixtures/specs/malformed-response.json"200": "this should be an object, not a scalar" を持つが、現状この fixture は OpenApiCoverageTrackerTest でのみ使われ、validator 経路では未テスト=このクラッシュ経路が露出している。

やること

  • OpenApiResponseValidator::validate()$responseSpec = $responses[$matchedResponseKey](line 190 付近)直後に、!is_array($responseSpec) ガードを追加し、Malformed 'responses[$matchedResponseKey]' for {METHOD} {path} in '{spec}' spec: expected object, got scalar. 形式の loud な spec エラーを OpenApiValidationResult::failure() で返す
  • RequestBodyValidatorrequestBody 非配列ガード(Malformed 'requestBody' ...)と対称
  • TDD: 非配列 responses[$status] エントリを持つ spec(malformed-response.json 流用可)に対し、未捕捉 TypeError ではなく isValid() === false + spec エラーが返ることを検証する失敗テストを先に追加

ゴール

  • 非配列 responses[$status] エントリで TypeError が出ず、RequestBodyValidator と同じ粒度の loud な spec エラーとして surface する
  • request/response で malformed-spec 検出の挙動が揃う

関連

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions