Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

エラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyo

535 views

Published on

2019-05-22 開催の「Laravel Meetup Tokyo Vol.12」におけるLT資料です

https://laravel-meetup-tokyo.connpass.com/event/124314

Published in: Software
  • Be the first to comment

  • Be the first to like this

エラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyo

  1. 1. okashoi@Laravel Meetup Tokyo Vol.12
  2. 2. • • • ← New!! • 6 • LT 1 • 🙇 #LaravelTokyo !2
  3. 3. !3
  4. 4. !4
  5. 5. !5 

  6. 6. https://speakerdeck.com/suzuken/phpcon2017 !6
  7. 7. • • • • • !7
  8. 8. HttpException 😄 !8
  9. 9. • ←DONE • • !9
  10. 10. • • • !10
  11. 11. • AppExceptionsHandler • report() • HTTP render() • IlluminateFoundationExceptionsHandler
  12. 12. • AppExceptionsHandler • report() • HTTP render() • IlluminateFoundationExceptionsHandler
  13. 13. IlluminateFoundationExceptionsHandler::render() !13 /** * Render an exception into a response. * * @param IlluminateHttpRequest $request * @param Exception $e * @return IlluminateHttpResponse|SymfonyComponentHttpFoundationResponse */ public function render($request, Exception $e) { if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); } $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { return $this->convertValidationExceptionToResponse($e, $request); } return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e); }
  14. 14. IlluminateFoundationExceptionsHandler::render() !14 /** * Render an exception into a response. * * @param IlluminateHttpRequest $request * @param Exception $e * @return IlluminateHttpResponse|SymfonyComponentHttpFoundationResponse */ public function render($request, Exception $e) { if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); } $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { return $this->convertValidationExceptionToResponse($e, $request); } return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e); } render
  15. 15. IlluminateFoundationExceptionsHandler::render() !15 /** * Render an exception into a response. * * @param IlluminateHttpRequest $request * @param Exception $e * @return IlluminateHttpResponse|SymfonyComponentHttpFoundationResponse */ public function render($request, Exception $e) { if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); } $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { return $this->convertValidationExceptionToResponse($e, $request); } return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e); }
  16. 16. IlluminateFoundationExceptionsHandler::render() !16 /** * Render an exception into a response. * * @param IlluminateHttpRequest $request * @param Exception $e * @return IlluminateHttpResponse|SymfonyComponentHttpFoundationResponse */ public function render($request, Exception $e) { if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); } $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { return $this->convertValidationExceptionToResponse($e, $request); } return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e); }
  17. 17. IlluminateFoundationExceptionsHandler::render() !17 /** * Render an exception into a response. * * @param IlluminateHttpRequest $request * @param Exception $e * @return IlluminateHttpResponse|SymfonyComponentHttpFoundationResponse */ public function render($request, Exception $e) { if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); } $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { return $this->convertValidationExceptionToResponse($e, $request); } return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e); } Contet-Type ON/OFF
  18. 18. • • • !18
  19. 19. !19 <?php namespace AppExceptions; /** * Class MyAppException * @package AppExceptions */ abstract class MyAppException extends Exception { /** * @return int HTTP ステータスコード */ abstract public function getStatusCode(): int; /** * @return string ユーザ向けのメッセージ */ abstract public function getUserMessage(): string; }
  20. 20. !20 <?php namespace AppExceptions; /** * Class MyAppException * @package AppExceptions */ abstract class MyAppException extends Exception { /** * @return int HTTP ステータスコード */ abstract public function getStatusCode(): int; /** * @return string ユーザ向けのメッセージ */ abstract public function getUserMessage(): string; } HTTP
  21. 21. !21 <?php namespace AppExceptions; /** * Class MyAppException * @package AppExceptions */ abstract class MyAppException extends Exception { /** * @return int HTTP ステータスコード */ abstract public function getStatusCode(): int; /** * @return string ユーザ向けのメッセージ */ abstract public function getUserMessage(): string; }
  22. 22. AppExceptionsHandler • report() 🙆 • HTTP 
 getStatusCode() getUserMessage() • → !22
  23. 23. IlluminateFoundationExceptionsHandler::render() !23 /** * Render an exception into a response. * * @param IlluminateHttpRequest $request * @param Exception $e * @return IlluminateHttpResponse|SymfonyComponentHttpFoundationResponse */ public function render($request, Exception $e) { if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); } $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { return $this->convertValidationExceptionToResponse($e, $request); } return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e); }
  24. 24. IlluminateFoundationExceptionsHandler::render() !24 /** * Render an exception into a response. * * @param IlluminateHttpRequest $request * @param Exception $e * @return IlluminateHttpResponse|SymfonyComponentHttpFoundationResponse */ public function render($request, Exception $e) { if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); } $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { return $this->convertValidationExceptionToResponse($e, $request); } return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e); }
  25. 25. IlluminateFoundationExceptionsHandler::prepareResponse() !25 /** * Prepare a response for the given exception. * * @param IlluminateHttpRequest $request * @param Exception $e * @return SymfonyComponentHttpFoundationResponse */ protected function prepareResponse($request, Exception $e) { if (! $this->isHttpException($e) && config('app.debug')) { return $this->toIlluminateResponse($this->convertExceptionToResponse($e), $e); } if (! $this->isHttpException($e)) { $e = new HttpException(500, $e->getMessage()); } return $this->toIlluminateResponse( $this->renderHttpException($e), $e ); }
  26. 26. IlluminateFoundationExceptionsHandler::prepareResponse() !26 /** * Prepare a response for the given exception. * * @param IlluminateHttpRequest $request * @param Exception $e * @return SymfonyComponentHttpFoundationResponse */ protected function prepareResponse($request, Exception $e) { if (! $this->isHttpException($e) && config('app.debug')) { return $this->toIlluminateResponse($this->convertExceptionToResponse($e), $e); } if (! $this->isHttpException($e)) { $e = new HttpException(500, $e->getMessage()); } return $this->toIlluminateResponse( $this->renderHttpException($e), $e ); } SymfonyComponentHttpKernelExceptionHttpException 
 HTTP
  27. 27. HttpException 
 😄 !27
  28. 28. HttpException 😄 !28 <?php namespace AppExceptions; use SymfonyComponentHttpKernelExceptionHttpException; /** * Class MyAppException * @package AppExceptions */ abstract class MyAppException extends Exception { /** * @return int HTTP ステータスコード */ abstract public function getStatusCode(): int; /** * @return string ユーザ向けのメッセージ */ abstract public function getUserMessage(): string; /** * @return HttpException */ public function toHttpException(): HttpException { return new HttpException( $this->getStatusCode(), $this->getUserMessage(), $this->getPrevious(), [], $this->code ); } } ※ JSON
  29. 29. AppExceptionsHandler !29 /** * Render an exception into an HTTP response. * * @param IlluminateHttpRequest $request * @param Exception $exception * @return IlluminateHttpResponse */ public function render($request, Exception $exception) { // 既存の render の仕組みを活用するため、HttpException に変換する if ($exception instanceof MyAppException) { $exception = $exception->toHttpException(); } return parent::render($request, $exception); }
  30. 30. !30 <?php namespace AppExceptions; use Throwable; /** * Class HogeException * @package AppExceptions */ abstract class HogeException extends MyAppException { /** * @return int HTTP ステータスコード */ public function getStatusCode(): int { return 500; } /** * @return string ユーザ向けのメッセージ */ public function getUserMessage(): string { return 'ごめん'; } } • • throw new HogeException('エラーです');
 • • Blade 
 $exception->getMessage()
 HTTP 

  31. 31. HttpException 😄 !31
  32. 32. • • Laravel 404 
 !32
  33. 33. +α URL https://github.com/okashoi/colab-techbook6-example !33
  34. 34. !34
  35. 35. 
 !35
  36. 36. IlluminateFoundationExceptionsHandler::report() !36 /** * Report or log an exception. * * @param Exception $e * @return mixed * * @throws Exception */ public function report(Exception $e) { if ($this->shouldntReport($e)) { return; } if (is_callable($reportCallable = [$e, 'report'])) { return $this->container->call($reportCallable); } try { $logger = $this->container->make(LoggerInterface::class); } catch (Exception $ex) { throw $e; } $logger->error( $e->getMessage(), array_merge($this->context(), ['exception' => $e] )); }
  37. 37. IlluminateFoundationExceptionsHandler::report() !37 /** * Report or log an exception. * * @param Exception $e * @return mixed * * @throws Exception */ public function report(Exception $e) { if ($this->shouldntReport($e)) { return; } if (is_callable($reportCallable = [$e, 'report'])) { return $this->container->call($reportCallable); } try { $logger = $this->container->make(LoggerInterface::class); } catch (Exception $ex) { throw $e; } $logger->error( $e->getMessage(), array_merge($this->context(), ['exception' => $e] )); }
  38. 38. IlluminateFoundationExceptionsHandler::report() !38 /** * Report or log an exception. * * @param Exception $e * @return mixed * * @throws Exception */ public function report(Exception $e) { if ($this->shouldntReport($e)) { return; } if (is_callable($reportCallable = [$e, 'report'])) { return $this->container->call($reportCallable); } try { $logger = $this->container->make(LoggerInterface::class); } catch (Exception $ex) { throw $e; } $logger->error( $e->getMessage(), array_merge($this->context(), ['exception' => $e] )); } report()
  39. 39. IlluminateFoundationExceptionsHandler::report() !39 /** * Report or log an exception. * * @param Exception $e * @return mixed * * @throws Exception */ public function report(Exception $e) { if ($this->shouldntReport($e)) { return; } if (is_callable($reportCallable = [$e, 'report'])) { return $this->container->call($reportCallable); } try { $logger = $this->container->make(LoggerInterface::class); } catch (Exception $ex) { throw $e; } $logger->error( $e->getMessage(), array_merge($this->context(), ['exception' => $e] )); } context

×