実際に動作確認はしていないのでイメージコードです🐱
もくじ
エラーハンドラー
利用イメージ
if ($user->type !== 'admin') { $title = config(validation.ADMIN.is_only_admin.title); $message = config(validation.ADMIN.is_only_admin.message); $errors = [ 'key' => 'type', 'value' => "管理者以外のユーザです。", ]; throw new AdminViewException($title, $message, $errors); }
AdminViewException
<?php namespace App\Exceptions\View; use App\Exceptions\View\ViewValidationException; class AdminViewException extends ViewValidationException { private $_status_code = config(validation.ADMIN.STATUS_CODE.FORBIDDEN); private $_view = config(views.error.default); public function __construct( string $title, string $message, array $errors ) { parent::__construct( $title, $message, $errors ) } public function getStatusCode(): int { return $this->_status_code; } public function getView(): string { return $this->_view; } }
ViewValidationException
<?php namespace App\Exceptions\View; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; abstract class ViewValidationException extends \RuntimeException implements HttpExceptionInterface { protected $view; protected $title = ""; protected $message = ""; protected $errors = []; public function __construct( string $title, string $message, string $description, ?string $view = config(views.error.default); ){ parent::__construct($message, $this->getStatusCode(), null); $this->setView($view); $this->setTitle($title); $this->setErrors($erros); } public function setView(string $view): void { $this->view = $view; } public function getView(): string { return $this->view; } public function setStatusCode(string $status_code): void { $this->status_code = $status_code; } public function getStatusCode(): int { return Response::HTTP_INTERNAL_SERVER_ERROR; } public function setTitle(string $title): void { $this->title = $title; } public function getTitle(): string { return $this->title; } public function setErrors(array $erros): void { $this->errors = $erros; } public function getErrors(): array { return $this->errors; } public function getHeaders() { return []; } }
ViewHandler
handler
<?php namespace App\Exceptions\View; use Illuminate\View\View; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; class ViewHandler extends ExceptionHandler { public function render($request, Exception $exception) { if ($exception instanceof \App\Exceptions\View\ViewException) { $view = $exception->getView(); $title = $exception->getTitle(); $status_code = $exception->getStatusCode(); $message = $exception->getMessage(); $this->_writeLogAlert($exception->getErrors()); return $this->_prepareViewResponse($view, $title, $status_code, $message); } } /* * アラートログに記録 * * @param array $errors * @return void */ private function _writeLogAlert(array $errors): void { Log::alert(json_encode($errors, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); } /* * ErrorViewへのレスポンスを生成して返却 * * @param string $view * @param string $title * @param int $status_code * @param string $message * @return Illuminate\View\View */ private function _prepareViewResponse(string $view, string $title, int $status_code, string $message): View { return view( $view, compact( $title, $status_code, $message ) ); } } }
AppServiceProvider
上記こしらえたViewHandlerをバインドさせます
class AppServiceProvider extends ServiceProvider { public function boot() { ... + if (strpos(\Request::getPathInfo(), '/web/api/v1/') === 0) { + $this->app->bind(\App\Exceptions\Handler::class, \App\Exceptions\View\ViewHandler::class); + } ... } }