2017-10-18 6 views
4

루멘을 사용하여 API 만들기 - Laravel을 좋아하지만 함께 제공되는 모든보기는 내가 만드는 프로젝트에 과도기였습니다.장인의 명령에서 예외를 깔끔하게 처리하는 방법

어쨌든, 나가서 데이터를 수집하고 데이터베이스에 저장하는 일련의 명령을 만들었습니다.

<?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

당신이 캐치 (\ 예외 $ 전자)} {시도'사용하려고 했 {}'내부 '-> fire()'메쏘드? 당신이 얻는 오류는 무엇입니까? 그 예외는 어디서 오는거야? – ljubadr

+0

@ljubadr 예, 해당 클래스에서만 작동하지만 많은 비슷한 클래스가 있으므로 try {} catch 블록을 반복해야합니다. 나는 예외를 스택 위로 던져서 스택 (stack)에서'fire()'가 호출되는 것을보다 깨끗하게 느낄 것입니다. – Moe

답변

3

답변은 명령이 예외를 throw 할 때 응용 프로그램이 수행하기를 원하는 것에 따라 다릅니다. 이 질문은 예외를 처리하는 데 필요한 방법을 설명하지 않으므로 몇 가지 옵션을 살펴 보겠습니다.

Laravel 및 Lumen 프로젝트에는 다양한 예외에 대한 동작을 정의하는 데 사용할 수있는 중앙 예외 Handler 클래스가 포함되어 있습니다. 이 클래스는 웹 요청과 콘솔 명령에서 발생하는 모든 예외를 처리합니다.

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); 
} 

, $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() 방법을 구현하는 : 중복 코드를 방지하기 위해, 우리는 세 가지 유사한 명령에 대한 구체적인 구현을 제공 추상적 클래스를 사용할 수 있습니다. 이 클래스에 다른 공유 논리를 추가 할 수 있습니다. 하위 명령은 getItems()의 특정 구현을 정의하기 만하면, 부모 클래스는 그들을 위해 예외를 처리합니다

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

이 Cy에 감사드립니다. 그것은 감각을 만든다. 이것은 Lumen의 Artisan Commands에도 적용됩니까? – Moe

+1

@Moe - 오신 것을 환영합니다! 그리고 네,이 답변의 정보는 또한 루멘에 적용됩니다. –

+0

디버그 정보가 포함 된 전자 메일을 보내려면 명령 수준 예외를 처리하고 싶습니다. – Moe