はじめに
これは Laravel Advent Calendar 2017 19日目の記事です。
カスタム例外処理(クラス)の作成と使用方法について書いていきます。
例外処理というと難解そうですが、結構簡単な内容なのですぐ読み終わると思います。
環境
- PHP: 7.1.5
- Laravel: 5.5.24
前提
- 今回は具体的な例として、バリデーションエラーの例外クラスを作成する
- レスポンスは JSON 形式
作成手順
例外クラスを作成する
-
artisan
コマンドで作成できる php artisan make:exception ValidationException
作成した例外クラスを編集する
app/Exceptions/ValidationException.php
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class ValidationException extends Exception
{
public $request;
public $message;
public function __construct(Request $request, array $message)
{
$this->request = $request;
// 複数のバリデーションエラー時には , で区切る
$this->message = implode(',', $message);
}
public function report()
{
$xRequestId = array_key_exists('x-request-id', $this->request->header()) ? $this->request->header()['x-request-id'][0] : '';
Log::info(
$xRequestId,
[
'client_ip' => $this->request->getClientIp(),
'request_params' => $this->request->all(),
'response_body' => $this->message,
]
);
}
public function render()
{
return response()->json(
$this->message,
422
);
}
}
解説
-
report()
ではログとして表示させたい内容を設定している -
render()
ではレスポンスとして返したい内容を設定している
作成した例外クラスを呼ぶ
会員登録の Controller
で呼び出してみる
app/Http/Controllers/Account/V1/RegisterController.php
<?php
namespace App\Http\Controllers\Account\V1;
use App\Exceptions\ValidationException;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class RegisterController extends Controller
{
public function apply(Request $request)
{
$validation = \Validator::make(
[
'mail_to' => $request->get('mail_to'),
'register_token' => $request->get('register_token'),
],
[
'mail_to' => 'required|email|max:128',
'register_token' => 'required|alpha_num|size:64',
]
);
if ($validation->fails()) {
throw new ValidationException($request, $validation->errors()->all());
}
...
}
}
ルーティング
routes/account/v1.php
Route::put('registers/apply', 'Account\V1\RegisterController@apply');
例外を発生させてみる
不正なリクエスト
- 必須パラメータである
register token
なし
curl -kv -X PUT -H "X-Request-Id: abc123" -d "mail_to=test@gmail.com" https://***-api.***.jp/account/v1/registers/apply
例外レスポンスの例
>
* upload completely sent off: 37 out of 37 bytes
< HTTP/1.1 422 Unprocessable Entity
< Server: nginx/1.12.1
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: no-cache, private
< Date: Mon, 11 Dec 2017 09:41:04 GMT
< X-RateLimit-Limit: 60
< X-RateLimit-Remaining: 57
<
* Curl_http_done: called premature == 0
* Connection #0 to host ***-api.***.jp left intact
"The register token field is required."
解説
-
register token
がリクエストパラメータに含まれていないため、The register token field is required.
というようにエラーレスポンスを返している - ステータスコードも
ValidationException
で設定した422
になっている
例外ログの例
[2017-12-11 09:41:04] local.INFO: test123 {"client_ip":"192.168.**.**","request_params":{"mail_to":"test@gmail.com"},"response_body":"The register token field is required."}
おまけ
去年の Laravel Advent Calendar にも参加していたので良かったらどうぞ。