今夜月明人尽望,不知秋思落谁家
自定义异常类 app\Exceptions\ExportException.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?php namespace App \Exceptions ;use Throwable ;class ExportException extends \Exception { protected $message ; public function __construct (string $message = "" , int $code = 0 , Throwable $previous = null ) { parent ::__construct($message , $code , $previous ); $this ->message = $message ; } public function report ( ) { } public function render ( ) { return response()->json(['status' => 200 , 'message' => $this ->message], 503 ); } }
说明: 如果在文件 app\Exceptions\Handler.php 中申明了以下代码, 针对该异常类的report
方法将不会在被执行;
1 2 3 4 5 6 7 8 9 10 11 12 class Handler extends ExceptionHandler { protected $dontReport = [ ExportException::class ];
抛出并捕获异常 首先尝试抛出异常:
1 2 3 4 5 try { $res = 1 /0 ; } catch (\App\Exceptions\ExportException $e ) { throw new \App\Exceptions\ExportException($e ->getMessage()); }
上面这段代码并不会在我们自定义的ExportException
中捕获, 而会在全局异常中捕获,原因我们打印出这个异常类型看看 app\Exceptions\Handler.php
1 2 3 4 5 6 public function render ($request , Exception $exception ) { dd(get_class($exception )); return parent ::render($request , $exception ); }
该异常类型属于ErrorException
, 并不是我们自定的ExportException
, 所以并不会被我们捕获; 我们可以这样, 既然我们已经知道这个异常类似是ErrorException
, 那么
1 2 3 4 5 try { $res = 1 /0 ; } catch ( ErrorException $e ) { throw new \App\Exceptions\ExportException($e ->getMessage()); }
当然也可以直接这样
1 2 3 4 5 try { $res = 1 /0 ; } catch ( Exception $e ) { throw new \App\Exceptions\ExportException($e ->getMessage()); }
这样就可以用我们自定义的异常类来捕捉从而进一步处理了
1 2 3 4 { "status" : 200 , "message" : "Division by zero" }
关于异常的理解
由程序员设计不足所导致的错误,需要用异常来捕捉和处理
程序在运行过程中, 有可能会发生一些不可预知的错误, 无法用if…else这样的语句来处理的时候.
函数无法满足调用方的期望的时候使用异常, 比如用户要请求一个API获得最新的商品信息, 但是查询结果为空的时候
所以我们自定义的异常可以是在不符合实现给定的情况下抛出的, 而不是真正程序在运行过程中发生了错误, 在Laravel的源码中我们可以找到很多一样的例子 vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php
1 2 3 4 5 6 protected function sendFailedLoginResponse (Request $request ) { throw ValidationException::withMessages([ $this ->username() => [trans('auth.failed' )], ]); }
vendor\guzzlehttp\psr7\src\functions.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 function str (MessageInterface $message ) { if ($message instanceof RequestInterface) { $msg = trim($message ->getMethod() . ' ' . $message ->getRequestTarget()) . ' HTTP/' . $message ->getProtocolVersion(); if (!$message ->hasHeader('host' )) { $msg .= "\r\nHost: " . $message ->getUri()->getHost(); } } elseif ($message instanceof ResponseInterface) { $msg = 'HTTP/' . $message ->getProtocolVersion() . ' ' . $message ->getStatusCode() . ' ' . $message ->getReasonPhrase(); } else { throw new \InvalidArgumentException ('Unknown message type' ); } foreach ($message ->getHeaders() as $name => $values ) { $msg .= "\r\n{$name} : " . implode(', ' , $values ); } return "{$msg} \r\n\r\n" . $message ->getBody(); }