laravel 中自定義異常

前言

項目上線時呕童,我們不能將系統(tǒng)的報錯信息反饋給用戶愧驱,因為這樣特別不安全和友好耗拓,所以我們要設置.env中APP_DEBUG = false次询。

盡管這樣不會在顯示代碼錯誤的信息,但是laravel會將顯示空白的 Whoops, looks like something went wrong镰烧,這無法給訪問者提供任何有價值的信息也不美觀拢军。

所以我們需要需要捕捉錯誤,處理它們怔鳖,然后用實際可以理解的錯誤信息返回給用戶茉唉。

源碼解析

首先看下laravel中的異常處理類:

app/Exceptions/Handler.php

 <?php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    // 不被處理的異常錯誤
    protected $dontReport = [
        InvalidRequestException::class,
    ];

    // 認證異常時不被flashed的數(shù)據(jù)
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    // 上報異常至錯誤driver,如日志文件(storage/logs/laravel.log),第三方日志存儲分析平臺
    public function report(Exception $exception)
    {
        parent::report($exception);
    }

    // 將異常信息響應給客戶端
    public function render($request, Exception $exception)
    {
        return parent::render($request, $exception);
    }
}

當 Laravel 處理一次請求時度陆,在啟動文件中注冊了以下服務:

bootstrap/app.php

.
.
// 綁定 http 服務提供者
$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);
// 綁定 cli 服務提供者
$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);
// 這里將異常處理器的服務提供者綁定到了 `App\Exceptions\Handler::class`
$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);
.
.

我們大概了解了異常艾凯,其中最主要的兩個方法是:

report() 如果你想要做一些額外的日志記錄,則使用report(), 比如將錯誤發(fā)送到電子郵件懂傀,Slack等趾诗。

render() 如果你想直接從Exception類重定向錯誤或返回HTTP響應(如自己的 Blade 文件),則使用render()

那么現(xiàn)在在自定義常用的兩個異常類:用戶錯誤行為觸發(fā)的異常和系統(tǒng)內(nèi)部異常

自定義異常

自定義常用的兩個異常:

  1. 用戶錯誤行為觸發(fā)的異常
  2. 系統(tǒng)內(nèi)部異常

用戶錯誤行為觸發(fā)的異常

$ php artisan make:exception InvalidRequestException

app/Exceptions/InvalidRequestException.php

<?php
namespace App\Exceptions;

use Exception;
use Illuminate\Http\Request;
use Throwable;

class InvalidRequestException extends Exception {
    public function __construct(string $message = "", int $code = 0, Throwable $previous = null) {
        parent::__construct($message, $code, $previous);
    }

    public function render(Request $request) {

        // 如果是 AJAX 請求則返回 JSON 格式的數(shù)據(jù)
        if ($request->expectsJson()) {
            return response()->json(['msg' => $this->message], $this->code);
        }

        return view('error', ['msg' => $this->message]);
    }
}


系統(tǒng)內(nèi)部異常

$ php artisan make:exception InternalException

app/Exceptions/InternalException.php

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Http\Request;
use Throwable;

class InternalException extends Exception {
    protected $msgForUser;

    public function __construct(string $message = "", string $msgForUser = "系統(tǒng)內(nèi)部錯誤", int $code = 0, Throwable $previous = null) {
        parent::__construct($message, $code, $previous);
        $this->msgForUser = $msgForUser;
    }

    public function render(Request $request) {

        if ($request->expectsJson()) {
            return response()->json(['msg' => $this->msgForUser], $this->code);
        }

        return view('error', ['msg' => $this->msgForUser]);
    }


}

應用到代碼中

拋出異常

use App\Exceptions\InvalidRequestException;
.
.
.
if (!$activate) {
    throw new InvalidRequestException('不再進行中');
}

參考

https://segmentfault.com/a/1190000018381889
https://juejin.im/entry/5af517c26fb9a07acd4dc5b8
https://swoole.app/2018/04/11/laravel%E4%BD%BF%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E5%BC%82%E5%B8%B8%E7%B1%BB/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蹬蚁,一起剝皮案震驚了整個濱河市恃泪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌犀斋,老刑警劉巖贝乎,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異叽粹,居然都是意外死亡览效,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門虫几,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锤灿,“玉大人,你說我怎么就攤上這事辆脸〉#” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵每强,是天一觀的道長。 經(jīng)常有香客問我州刽,道長空执,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任穗椅,我火速辦了婚禮辨绊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘匹表。我一直安慰自己门坷,他們只是感情好,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布袍镀。 她就那樣靜靜地躺著默蚌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苇羡。 梳的紋絲不亂的頭發(fā)上绸吸,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天,我揣著相機與錄音,去河邊找鬼锦茁。 笑死攘轩,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的码俩。 我是一名探鬼主播度帮,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼稿存!你這毒婦竟也來了笨篷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤挠铲,失蹤者是張志新(化名)和其女友劉穎冕屯,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拂苹,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡安聘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓢棒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浴韭。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖脯宿,靈堂內(nèi)的尸體忽然破棺而出念颈,到底是詐尸還是另有隱情,我是刑警寧澤连霉,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布榴芳,位于F島的核電站,受9級特大地震影響跺撼,放射性物質(zhì)發(fā)生泄漏窟感。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一歉井、第九天 我趴在偏房一處隱蔽的房頂上張望柿祈。 院中可真熱鬧,春花似錦哩至、人聲如沸躏嚎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卢佣。三九已至,卻和暖如春箭阶,著一層夾襖步出監(jiān)牢的瞬間珠漂,已是汗流浹背晚缩。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留媳危,地道東北人荞彼。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像待笑,于是被迫代替她去往敵國和親鸣皂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容