PHP

Laravel エラーハンドリング

Laravel

 

実際に動作確認はしていないのでイメージコードです🐱

 

エラーハンドラー

 

利用イメージ

 

    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);
    +      }
        ...
    }
}

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)