Lumen 5.4。
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
中的以下函数:
/**
* 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));
}
};
}
它被抓到那里,所以我AfterMiddleware
没用。任何想法如何绕过它?我找到了一个解决方案,并将所有例外情况移到render()
类的Handler
中,但使用中间件更方便。
答案 0 :(得分:1)
我还没试过这个,但是从Lumen的代码来看,我认为这是可能的。
从handleException
调用的prepareDestination
函数检查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
);
答案 1 :(得分:-1)
这就是我处理我的方法,它处理Lumen 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);
}
}
}