Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Laravelのエラーハンドリングをカスタマイズする

Avatar for Kazuhei Arai Kazuhei Arai
December 16, 2020

 Laravelのエラーハンドリングをカスタマイズする

Avatar for Kazuhei Arai

Kazuhei Arai

December 16, 2020
Tweet

More Decks by Kazuhei Arai

Other Decks in Programming

Transcript

  1. ς Ϋ ϊ ϩ δ ʔ ͷ ྗ Ͱ M

    & A ʹ ྲྀ ௨ ֵ ໋ Λ
  2. 1)1ͷ&YDFQUJPO &SSPS͸&YDFQUJPOͰ͸ͳ͍ͷͰ5ISPXBCMFͱͯ͠$BUDI <?php /** * Handle an incoming HTTP request.

    * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function handle($request) { try { throw new SomeException(); } catch (Exception $e) { // ExceptionͷΈCatch } catch (Throwable $e) { // ExceptionͱErrorͷ྆ํΛCatch } }
  3. ΤϥʔϋϯυϦϯά·ͰͷྲྀΕ QVCMJDJOEFYQIQͰ,FSOFMΛੜ੒͠,FSOFMIBOEMF Λ࣮ߦ <?php /** * Laravel - A PHP

    Framework For Web Artisans * * @package Laravel * @author Taylor Otwell <[email protected]> */ define('LARAVEL_START', microtime(true)); /** ུ **/ $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); $response->send(); $kernel->terminate($request, $response);
  4. ΤϥʔϋϯυϦϯά·ͰͷྲྀΕ *MMVNJOBUFa'PVOEBUJPOa)UUQa,FSOFMIBOEMF಺Ͱ &YDFQUJPOɺ5ISPXBCMFΛर͏ <?php /** লུ **/ public function handle($request)

    { try { $request->enableHttpMethodParameterOverride(); $response = $this->sendRequestThroughRouter($request); } catch (Exception $e) { $this->reportException($e); $response = $this->renderException($request, $e); } catch (Throwable $e) { $this->reportException($e = new FatalThrowableError($e)); $response = $this->renderException($request, $e); } $this->app['events']->dispatch( new RequestHandled($request, $response) ); return $response; }
  5. ΤϥʔϋϯυϦϯά·ͰͷྲྀΕ &SSPS΋'BUBM5ISPXBCMF&SSPSͱ͍͏໊લͷ &SSPS&YDFQUJPOʹม׵͍ͯ͠Δ <?php /** লུ **/ public function handle($request)

    { try { $request->enableHttpMethodParameterOverride(); $response = $this->sendRequestThroughRouter($request); } catch (Exception $e) { $this->reportException($e); $response = $this->renderException($request, $e); } catch (Throwable $e) { $this->reportException($e = new FatalThrowableError($e)); $response = $this->renderException($request, $e); } $this->app['events']->dispatch( new RequestHandled($request, $response) ); return $response; }
  6. ΤϥʔϋϯυϦϯά·ͰͷྲྀΕ ͭ·Γɺ-BSBWFMͷ࣮ߦ࣌ʹൃੜͨ͠&SSPS͸࠷ऴతʹ શͯ&YDFQUJPOʹม׵͞Ε͔ͯΒॲཧ͞ΕΔ <?php /** লུ **/ public function handle($request)

    { try { $request->enableHttpMethodParameterOverride(); $response = $this->sendRequestThroughRouter($request); } catch (Exception $e) { $this->reportException($e); $response = $this->renderException($request, $e); } catch (Throwable $e) { $this->reportException($e = new FatalThrowableError($e)); $response = $this->renderException($request, $e); } $this->app['events']->dispatch( new RequestHandled($request, $response) ); return $response; }
  7. ΤϥʔϋϯυϦϯά·ͰͷྲྀΕ <?php /** লུ **/ /** * Report the exception

    to the exception handler. * * @param \Exception $e * @return void */ protected function reportException(Exception $e) { $this->app[ExceptionHandler::class]->report($e); } /** * Render the exception to a response. * * @param \Illuminate\Http\Request $request * @param \Exception $e * @return \Symfony\Component\HttpFoundation\Response */ protected function renderException($request, Exception $e) { return $this->app[ExceptionHandler::class]->render($request, $e); } ΤϥʔϋϯυϦϯά͸&YDFQUJPO)BOEMFSDMBTTͷ࣮૷͕ߦ͏
  8. ΤϥʔϋϯυϦϯάͷྲྀΕ <?php /** লུ **/ 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 ); } σϑΥϧτͷQSFQBSF3FTQPOTFʹ͸&YDFQUJPOΛड͚औͬͯ ඳը͢Δ࠷௿ݶͷॲཧ͕ॻ͍ͯ͋Δ
  9. ಛఆͷ&YDFQUJPOΛϩάʹग़͞ͳ͘͢Δ EPOU3FQPSUΛࢦఆͯ͠ϩάʹग़͞ͳ͍ <?php namespace Illuminate\Foundation\Exceptions; /** ུ **/ class Handler

    extends ExceptionHandler {
 
 /** ུ **/ protected function shouldntReport(Exception $e) { $dontReport = array_merge($this->dontReport, $this->internalDontReport); return ! is_null(Arr::first($dontReport, function ($type) use ($e) { return $e instanceof $type; })); }
  10. ಛఆͷ&YDFQUJPOΛϩάʹग़͞ͳ͘͢Δ EPOU3FQPSUΛࢦఆͯ͠ϩάʹग़͞ͳ͍ <?php namespace App\Exceptions; /** ུ **/ class Handler

    extends ExceptionHandler { /** * A list of the exception types that are not reported. * * @var array */ protected $dontReport = [ PreconditionException::class, NotFoundException::class, ];
  11. ಠࣗͷ&YDFQUJPOͰطଘͷΤϥʔදࣔΛ͢Δ )UUQ&YDFQUJPOΛܧঝͨ͠Ϋϥεʹม׵͢Δ <?php namespace App\Exceptions; /** ུ **/ class Handler

    extends ExceptionHandler { protected function prepareException(Exception $e) { $e = parent::prepareException($e); if ($e instanceof NotFoundException) { $e = new NotFoundHttpException($e->getMessage(), $e); } if ($e instanceof PreconditionException) { $e = new AccessDeniedHttpException($e->getMessage(), $e); } return $e; }
  12. ΤϥʔදࣔͷWJFXΛΧελϚΠζ͢Δ <?php namespace App\Exceptions; /** ུ **/ class Handler extends

    ExceptionHandler { protected function prepareResponse($request, Exception $e) { return $this->toIlluminateResponse( $this->customRenderHttpException($request, $e), $e ); } private function customRenderHttpException(Request $request, HttpException $e) { $status = $e->getStatusCode(); $paths = collect(config('view.paths')); view()->replaceNamespace('errors', $paths->map(function ($path) use ($request) { if ($request->is('admin/*')) { return "{$path}/admin/errors"; } return "{$path}/service/errors"; })->push(__DIR__ . '/views')->all());
 
 if (view()->exists($view = "errors::{$status}")) { return response()->view($view, ['exception' => $e], $status, $e->getHeaders()); } return $this->convertExceptionToResponse($e); }