Laravel 8.x Validationエラーで常に200 OKが返る
一応使ってるのは、Laravel 8.47.0
APIを実装していて、入力内容の検証にValidatorを使うと
エラー発生時、常にstatus code 200が返される。
この問題はLaravel 5.xでもあったようで、同じ問題に遭遇している人はいたらしいが
その時は、RequestにAccept:application/jsonを含めればいいということで解決していたらしい。
しかしやってみたけど、うまくいかなかった。
今回はRequestFormを使って検証してみたが、普通にRequestのvalidatorを使っても結果は同じであった。
LaravelのRequestFormクラスでは、検証失敗時に以下のメソッドが呼ばれて例外が投げられるらしい。
/**
* Handle a failed validation attempt.
*
* @param \Illuminate\Contracts\Validation\Validator $validator
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function failedValidation(Validator $validator)
{
throw (new ValidationException($validator))
->errorBag($this->errorBag)
->redirectTo($this->getRedirectUrl());
}
ValidationExceptionの中を見るとメンバに$status = 422というのがおり、そもそも422を返すおつもりであることはうかがえる。
しかしなぜか200が返る。
このメソッドをオーバーライドすることもできるので、自分で作ったRequestFormクラスにて
以下のようにオーバーライドしてみた。
/**
* オーバライドした。
*
* @param \Illuminate\Contracts\Validation\Validator $validator
* @return void
*
* @throws \Illuminate\Validation\HttpResponseException
*/
protected function failedValidation(Validator $validator)
{
$error = (new ValidationException($validator))->errors();
throw new HttpResponseException(response()->json($error, 422));
}
オーバーライドはされて処理もちゃんと動いているようだが、これでも200 OKが返される。
もうindex.phpが追いかけていくしかないが、めんどくさいので
力が蓄えられるまではやらない。
‘app/Exceptions/Handler.php'
protected function invalidJson($request, ValidationException $exception)
{
return response()->json([
'message' => $exception->getMessage(),
'errors' => $exception->errors(),
], 422);
}
invalidJsonをオーバライドしても結果は同じで200OKが返却される。
環境のおさらい
Laravel 8.47.0
Docker for Windows
- web:Nginx
- app:PHP-fpm
- db:MySQL
コンテナは上記3つを組み合わせた環境。
今のところトリガーはValidationExceptionが発生したときにおこるということ
例外を発生させずにresponse()->json([], 422)をすると422が返る。
このあたりを色んなケースで試してみるのがいいか🤔
解決した。
validation.phpの先頭に改行はいってただけといううんちみたいな理由でした。
原因究明の経緯はTwitterで騒いでたので、そちらを残す。