2017-10-18 151 views
4

使用Lumen創建一個API--愛Laravel,但所有與View一起的View對於我創建的項目來說都是過度的。如何巧妙地處理Artisan命令中的例外

無論如何,我已經做出了一系列命令,它們出去收集數據並將其存儲到數據庫中。

<?php 

namespace App\Console\Commands; 

use Illuminate\Console\Command; 
use Symfony\Component\Console\Input\InputOption; 

use App\User; 

class GetItems extends Command { 

    /** 
    * The console command name. 
    * 
    * @var string 
    */ 
    protected $name = 'GetItems'; 

    /** 
    * The console command description. 
    * 
    * @var string 
    */ 
    protected $description = "Get items and store it into the Database"; 

    /** 
    * Execute the console command. 
    * 
    * @return void 
    */ 
    public function fire() 
    { 
     $this->info("Collecting ..."); 

     $users = User::all(); 

     foreach($users as $user) 
     { 
      $user->getItems(); 
     } 

    } 

    /** 
    * Get the console command options. 
    * 
    * @return array 
    */ 
    protected function getOptions() 
    { 
     return []; 
    } 

} 

我有3個類似的命令,每一個都收集稍微不同的數據集。

有沒有一種方法可以注入一箇中間層,捕獲來自我的命令中每個fire()函數的異常?我正在考慮擴展Command類 - 但是想看看框架創建者是否已經有一種方法可以實現推薦(文檔/搜索沒有幫助)。

我知道替代方法是將所有命令組合成一個文件並使用選項,但是這使得它很難與之協作。

有什麼建議嗎?

+0

你嘗試使用'嘗試{}趕上(\例外$ E){}'內' - > fire()'方法?你得到的錯誤是什麼?那個異常來自哪裏? – ljubadr

+0

@ljubadr是的,只能在該類中工作,但因爲我有許多類似的類,所以我必須重複try {} catch塊。我覺得將一個異常向上堆棧並將其捕獲到堆棧中'fire()'被調用 – Moe

回答

3

答案取決於我們希望應用程序在命令引發異常時執行的操作。這個問題沒有描述處理異常的理想方式,所以我們來看幾個選項。

Laravel和Lumen項目包括一箇中心例外Handler類,我們可以使用它來定義不同例外的行爲。該類處理從Web請求和控制檯命令冒出的任何異常。

Laravel使用report()方法中的 app/Exceptions/Handler.php來確定如何記錄異常。我們可以在這裏添加邏輯錯誤報告:

public function report(Exception $e) 
{ 
    if ($e instanceof CustomConsoleException) { 
     // do something specific... 
    } 
    ... 
} 

renderForConsole()方法讓我們定製,我們要如何顯示控制檯命令的錯誤和異常消息。該項目的異常Handler通常不包含此方法定義,但如果需要,我們可以在應用程序/例外/ Handler.php覆蓋它:

public function renderForConsole($output, Exception $e) 
{ 
    $output->writeln('Something broke!'); 

    (new ConsoleApplication)->renderException($e, $output); 
} 

在上面的例子中,$output是一個Symfony\Component\Console\Output \OutputInterface參考對象,我們可以使用它將文本寫入控制檯命令的輸出流。

正如我們從上面可以猜到的那樣,中央異常處理程序被設計用於處理我們的代碼在較低級別處理未捕獲的異常,所以當我們需要在異常後執行某些特定操作時,它並不是非常有用。以類似的方式,我們可以覆蓋app/Console/Kernel.php中的reportException()renderException()方法。

如果我們需要做一些具體的事情,除了只承認一個命令通過顯示一條消息來拋出一個異常,我們實際上應該把這個邏輯寫入命令本身。爲了避免重複的代碼,我們可以使用一個抽象類,這三個類似的命令爲提供具體實現:

abstract class AbstractGetItems extends Command 
{ 
    ... 
    final public function fire() 
    { 
     try { 
      $this->getItems(); 
     } catch (Exception $e) { 
      // handle exception... 
     } 
    } 

    abstract protected function getItems(); 
} 

這個抽象命令強制子類來實現getItems()方法,它的類fire()自動調用。我們可以添加任何其他共享邏輯到這個類。子命令只需要定義自己的具體實施getItems(),和父類將處理異常爲他們:

class GetSpecificItems extends AbstractGetItems 
{ 
    ... 
    protected function getItems() 
    { 
     // fetch specific items... 
    } 
} 
+0

感謝這個Cy。它使感官。這是否也適用於流明中的Artisan命令? – Moe

+1

@莫 - 不客氣!是的,這個答案中的信息也適用於流明。 –

+0

我想我想處理命令級別的異常給我發送一封包含調試信息的電子郵件 – Moe

相關問題