2017-10-18 21 views
4

Lumenを使用してAPIを作成する - Laravelが大好きですが、それに付随するすべての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クラスを拡張することを考えていましたが、既にそれを行う方法があるかどうかを知りたければ、を推奨しました(ドキュメンテーション/検索は役に立たなかった)。

私は、すべてのコマンドを1つのファイルにまとめてオプションを使用する方法があると知っていますが、これは面倒で難しくなります。

提案がありますか?

+0

あなたは 'しようと{}キャッチ(\例外の$ e)の{}'内部を使用しようとしました' - > fire()'メソッド?あなたが得たエラーは何ですか?その例外はどこから来ていますか? – ljubadr

+0

@ljubadrはい、そのクラスでのみ動作しますが、私は多くの同様のクラスを持っているので、try {} catchブロックを繰り返す必要があります。スタックの上に例外をスローし、 'fire()'が呼び出されるスタックにキャッチすると、クリーナーになると感じています – Moe

答えて

3

答えは、コマンドが例外をスローしたときにアプリケーションが実行させたいものによって決まります。問題は、例外を処理するための望ましい方法を説明していないので、いくつかのオプションを見てみましょう。

LaravelとLumenプロジェクトには、異なる例外に対する動作を定義するために使用できる中央例外Handlerクラスが含まれています。このクラスは、Webリクエストやコンソールコマンドからバブルアップする例外を処理します。

Laravelは、メソッドを 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); 
} 

$outputSymfony\Component\Console\Output \OutputInterfaceへの参照ですオブジェクトを使用して、コンソールコマンドの出力ストリームにテキストを書き込むことができます。

中央の例外ハンドラは、コードが下位レベルで処理しない未知の例外を処理するように設計されているため、例外の後に特定のアクションを実行する必要がある場合はあまり役に立ちません。同様の方法でapp/Console/Kernel.phpreportException()renderException()メソッドを上書きできます。

コマンドがメッセージを表示して例外をスローしたことを確認する以外に、具体的なことを行う必要がある場合は、このロジックをコマンド自体に書き込む必要があります。

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

    abstract protected function getItems(); 
} 

この抽象コマンドを強制的に子クラスは、クラスがfire()で自動的に呼び出すgetItems()メソッドを実装するには、次のコードの重複を避けるために、我々は3つの同様のコマンドがための具体的な実装を提供抽象クラスを使用することができます。このクラスには他の共有ロジックを追加できます。子コマンドはgetItems()の彼らの特定の実装を定義するだけで済み、および親クラスは、彼らのために例外を処理します:

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

このCyのおかげで。それは感覚を作ります。これはルーメン内のアーティザンコマンドにもあてはまりますか? – Moe

+1

@Moe - ようこそ!そして、はい、この回答の情報はルーメンにも当てはまります。 –

+0

私は、コマンドレベルの例外を処理して、デバッグ情報を電子メールで送信したいと思っています。 – Moe

関連する問題