例外処理
設定
config/exception.php
return [
// ここで例外処理クラスを設定します
'' => support\exception\Handler::class,
];
マルチアプリケーションモードの場合は、各アプリケーションごとに例外処理クラスを個別に設定できます。詳細はマルチアプリケーションを参照してください。
デフォルト例外処理クラス
webmanでは、例外はデフォルトで support\exception\Handler
クラスによって処理されます。デフォルトの例外処理クラスを変更するには、設定ファイルconfig/exception.php
を修正してください。例外処理クラスはWebman\Exception\ExceptionHandlerInterface
インターフェースを実装する必要があります。
interface ExceptionHandlerInterface
{
/**
* ログの記録
* @param Throwable $e
* @return mixed
*/
public function report(Throwable $e);
/**
* レンダリング応答
* @param Request $request
* @param Throwable $e
* @return Response
*/
public function render(Request $request, Throwable $e) : Response;
}
レンダリング応答
例外処理クラスのrender
メソッドは応答をレンダリングするために使用されます。
設定ファイルconfig/app.php
のdebug
値がtrue
の場合(以下 app.debug=true
)、詳細な例外情報が返されます。そうでない場合は、簡略な例外情報が返されます。
もしリクエストがjsonでの応答を期待している場合、返される例外情報はjson形式で返され、次のようになります。
{
"code": "500",
"msg": "例外情報"
}
app.debug=true
の場合、jsonデータには追加のtrace
フィールドが含まれ、詳細なコールスタックが返されます。
独自の例外処理クラスを作成して、デフォルトの例外処理ロジックを変更することができます。
ビジネス例外 BusinessException
時には、特定のネストした関数内でリクエストを中断し、エラーメッセージをクライアントに返したい場合があります。その場合、BusinessException
をスローすることでこれを実現できます。
例えば:
<?php
namespace app\controller;
use support\Request;
use support\exception\BusinessException;
class FooController
{
public function index(Request $request)
{
$this->chackInpout($request->post());
return response('hello index');
}
protected function chackInpout($input)
{
if (!isset($input['token'])) {
throw new BusinessException('パラメータエラー', 3000);
}
}
}
上記の例は次のような応答を返します。
{"code": 3000, "msg": "パラメータエラー"}
注意
ビジネス例外BusinessExceptionはビジネスにおいてtryで捕捉する必要はなく、フレームワークが自動で捕捉し、リクエストの種類に応じた適切な出力を返します。
カスタムビジネス例外
上記の応答がニーズに合わない場合、例えばmsg
をmessage
に変更したい場合、MyBusinessException
をカスタム作成できます。
新たにapp/exception/MyBusinessException.php
を作成し、内容は次のようにします。
<?php
namespace app\exception;
use support\exception\BusinessException;
use Webman\Http\Request;
use Webman\Http\Response;
class MyBusinessException extends BusinessException
{
public function render(Request $request): ?Response
{
// jsonリクエストはjsonデータを返します
if ($request->expectsJson()) {
return json(['code' => $this->getCode() ?: 500, 'message' => $this->getMessage()]);
}
// 非jsonリクエストの場合はページを返します
return new Response(200, [], $this->getMessage());
}
}
このように、ビジネスロジックで次のように呼び出すと
use app\exception\MyBusinessException;
throw new MyBusinessException('パラメータエラー', 3000);
jsonリクエストは次のようなjson応答を受け取ります。
{"code": 3000, "message": "パラメータエラー"}
ヒント
BusinessException
例外はビジネス例外(例えばユーザーの入力パラメータエラー)に属するため、予測可能であり、フレームワークはこれを致命的なエラーとは見なさず、ログを記録しません。
まとめ
現在のリクエストを中断し、情報をクライアントに返す必要がある場合はBusinessException
例外の使用を考慮してください。