2017-05-23 5 views
0

ルーメン5.4。LumenのAfterMiddleware内の例外を捕まえるには?

/** 
* Get the initial slice to begin the stack call. 
* 
* @param \Closure $destination 
* @return \Closure 
*/ 
protected function prepareDestination(BaseClosure $destination) 
{ 
    return function ($passable) use ($destination) { 
     try { 
      return call_user_func($destination, $passable); 
     } catch (Exception $e) { 
      return $this->handleException($passable, $e); 
     } catch (Throwable $e) { 
      return $this->handleException($passable, new FatalThrowableError($e)); 
     } 
    }; 
} 

をそして、それはそこにcatchedだので、私は私のAfterMiddlewareは無用です:例外が発生した後

class AfterMiddleware 
{ 
    public function handle($request, Closure $next) 
    { 
     try { 
      return $next($request); 
     } catch (IpValidationException $e) { 
      return response()->json($e->getMessage(), 422); 
     } catch (RemoteException $e) { 
      return response()->json($e->getMessage(), 503); 
     } catch (BaseException $e) { 
      return response()->json($e->getMessage(), 400); 
     } catch (\Exception $e) { 
      return response()->json($e->getMessage(), $e->getCode()); 
     } 
    } 
} 

$next($request)Laravel\Lumen\Routingに次の関数になります。どのようにそれを回避するための任意のアイデア?解決策を見つけて、すべての例外をHandlerクラスのrender()に移動しましたが、ミドルウェアを使用する方がはるかに便利です。

答えて

1

私はこれを試していませんが、ルーメンのコードから、私は可能だと思います。

prepareDestinationから呼び出されるhandleException関数は、ExceptionHanlderがコンテナにバインドされているかどうかをチェックします。そうでない場合は、例外がスローされます。

protected function handleException($passable, Exception $e) 
    { 
     if (! $this->container->bound(ExceptionHandler::class) || ! $passable instanceof Request) { 
      throw $e; 
     } 

     $handler = $this->container->make(ExceptionHandler::class); 

     $handler->report($e); 

     return $handler->render($passable, $e); 
    } 

ので、*。、これは私が地雷を処理する方法であるbootstrap/app.php

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class, 
    App\Exceptions\Handler::class 
); 
+0

私はこれを逃しました。私が今ハンドラクラスで必要なロジックを持っていた唯一の問題は、これにもかかわらず、あなたの解決策を知ることです! – wujt

+0

いくつかの考えの後、あなたがExceptionHandlerなしで滞在するなら、それは良い考えではないようです。したがって、これを使用しないことが最良のアイデアではないため、他のいくつかの例外は自動的に処理されません。 – wujt

-1

から結合exceptionHandlerの下に除去することにより、ルーメン5.5にその作業をしようとすると、PHP 7.1。

遅い回答ですが、うまくいけば、それは他の人に役立つでしょう。

<?php 

namespace App\Exceptions; 

use Exception; 
use Illuminate\Auth\Access\AuthorizationException; 
use Illuminate\Database\Eloquent\ModelNotFoundException; 
use Illuminate\Http\Response; 
use Illuminate\Validation\ValidationException; 
use Laravel\Lumen\Exceptions\Handler as ExceptionHandler; 
use Symfony\Component\HttpKernel\Exception\HttpException; 
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; 
use Illuminate\Http\Exception\HttpResponseException; 
use Symfony\Component\Debug\Exception\FatalThrowableError; 


class Handler extends ExceptionHandler 
{ 
    /** 
    * A list of the exception types that should not be reported. 
    * 
    * @var array 
    */ 
    protected $dontReport = [ 
     AuthorizationException::class, 
     HttpException::class, 
     ModelNotFoundException::class, 
     ValidationException::class, 
    ]; 

    /** 
    * Report or log an exception. 
    * 
    * This is a great spot to send exceptions to Sentry, Bugsnag, etc. 
    * 
    * @param \Exception $e 
    * @return void 
    */ 
    public function report(Exception $e) 
    { 
     parent::report($e); 
    } 

    /** 
    * Render an exception into an HTTP response. 
    * 
    * @param \Illuminate\Http\Request $request 
    * @param \Exception $e 
    * @return \Illuminate\Http\Response 
    */ 
    public function render($request, Exception $e) 
    { 
     // if (env('APP_DEBUG')) { 
     //  return parent::render($request, $e); 
     // } 
     $response = [ 
      'success' => false 
     ]; 
     $response['status'] = null; 

     if ($e instanceof HttpResponseException) { 
      $response['status'] = Response::HTTP_INTERNAL_SERVER_ERROR; 
     } elseif ($e instanceof MethodNotAllowedHttpException) { 
      $response['status'] = Response::HTTP_METHOD_NOT_ALLOWED; 
     } elseif ($e instanceof NotFoundHttpException) { 
      $response['status'] = Response::HTTP_NOT_FOUND; 
     } elseif ($e instanceof AuthorizationException) { 
      $response['status'] = Response::HTTP_FORBIDDEN; 
      $e  = new AuthorizationException('HTTP_FORBIDDEN', $response['status']); 
     } elseif ($e instanceof ValidationException && $e->getResponse()) { 
      $response['status'] = Response::HTTP_BAD_REQUEST; 
      $e  = new ValidationException('HTTP_BAD_REQUEST', $response['status'], $e); 
     } elseif ($e instanceof ValidationException) { 
      $response['status'] = 422; 
      $response['errors'] = $e->validator->errors(); 
     } elseif ($e instanceof ModelNotFoundException) { 
      $response['status'] = 404; 
     } elseif ($e instanceof UnableToExecuteRequestException) { 
      $response['status'] = $e->getCode(); 
     } elseif ($e instanceof FatalThrowableError) { 
      $response['status'] = Response::HTTP_INTERNAL_SERVER_ERROR; 
     } elseif ($e) { 
      $response['status'] = Response::HTTP_INTERNAL_SERVER_ERROR; 
      $response['unhandled'] = 'exception-lumen-ksoft'; 
     } 

     if ($response['status']) { 
      $response['message'] = $e->getMessage(); 
      $response['error_code'] = $e->getCode() ?? ''; 
      // $response['exception'] = $e->getTraceAsString() ?? ''; 
      if (app()->environment() == 'local'){ 
       $response['file'] = $e->getFile() ?? ''; 
       $response['line'] = $e->getLine() ?? ''; 
      } 
      return response()->json($response, $response['status']); 
     } else { 
      return parent::render($request, $e); 
     } 

    } 
} 
関連する問題