zoukankan      html  css  js  c++  java
  • Lumen开发:Lumen的异常处理机制

    版权声明:本文为博主原创文章,未经博主允许不得转载。

    Lumen的核心类Application引用了专门用于异常处理的RegistersExceptionHandlers,

    class Application extends Container
    {
        use ConcernsRoutesRequests,
            ConcernsRegistersExceptionHandlers;
    

    直接来看一下这个引用里的方法RegistersExceptionHandlers.php

    <?php
    
    namespace LaravelLumenConcerns;
    
    use Error;
    use ErrorException;
    use SymfonyComponentConsoleOutputConsoleOutput;
    use SymfonyComponentHttpKernelExceptionHttpException;
    use SymfonyComponentDebugExceptionFatalErrorException;
    use SymfonyComponentDebugExceptionFatalThrowableError;
    use SymfonyComponentHttpKernelExceptionNotFoundHttpException;
    
    trait RegistersExceptionHandlers
    {
        /**
         * Throw an HttpException with the given data.(通过给定的数据HttpException。)
         *
         * @param  int     $code
         * @param  string  $message
         * @param  array   $headers
         * @return void
         *
         * @throws SymfonyComponentHttpKernelExceptionHttpException
         */
        public function abort($code, $message = '', array $headers = [])
        {
            if ($code == 404) {
                throw new NotFoundHttpException($message);
            }
    
            throw new HttpException($code, $message, null, $headers);
        }
    
        /**
         * Set the error handling for the application.(设置应用程序的错误处理。)
         *
         * @return void
         */
        protected function registerErrorHandling()
        {
            error_reporting(-1);
    
            set_error_handler(function ($level, $message, $file = '', $line = 0) {
                if (error_reporting() & $level) {
                    throw new ErrorException($message, 0, $level, $file, $line);
                }
            });
    
            set_exception_handler(function ($e) {
                $this->handleUncaughtException($e);
            });
    
            register_shutdown_function(function () {
                $this->handleShutdown();
            });
        }
    
        /**
         * Handle the application shutdown routine.(处理关闭应用程序。)
         *
         * @return void
         */
        protected function handleShutdown()
        {
            if (! is_null($error = error_get_last()) && $this->isFatalError($error['type'])) {
                $this->handleUncaughtException(new FatalErrorException(
                    $error['message'], $error['type'], 0, $error['file'], $error['line']
                ));
            }
        }
    
        /**
         * Determine if the error type is fatal.(如果确定的错误类型是致命的。)
         *
         * @param  int  $type
         * @return bool
         */
        protected function isFatalError($type)
        {
            $errorCodes = [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE];
    
            if (defined('FATAL_ERROR')) {
                $errorCodes[] = FATAL_ERROR;
            }
    
            return in_array($type, $errorCodes);
        }
    
        /**
         * Send the exception to the handler and return the response.(将异常发送给处理程序并返回响应。)
         *
         * @param  Throwable  $e
         * @return Response
         */
        protected function sendExceptionToHandler($e)
        {
            $handler = $this->resolveExceptionHandler();
    
            if ($e instanceof Error) {
                $e = new FatalThrowableError($e);
            }
    
            $handler->report($e);
    
            return $handler->render($this->make('request'), $e);
        }
    
        /**
         * Handle an uncaught exception instance.(处理未捕获的异常情况。)
         *
         * @param  Throwable  $e
         * @return void
         */
        protected function handleUncaughtException($e)
        {
            $handler = $this->resolveExceptionHandler();
    
            if ($e instanceof Error) {
                $e = new FatalThrowableError($e);
            }
    
            $handler->report($e);
    
            if ($this->runningInConsole()) {
                $handler->renderForConsole(new ConsoleOutput, $e);
            } else {
                $handler->render($this->make('request'), $e)->send();
            }
        }
    
        /**
         * Get the exception handler from the container.(从容器中获取异常处理程序。)
         *
         * @return mixed
         */
        protected function resolveExceptionHandler()
        {
            if ($this->bound('IlluminateContractsDebugExceptionHandler')) {
                return $this->make('IlluminateContractsDebugExceptionHandler');
            } else {
                return $this->make('LaravelLumenExceptionsHandler');
            }
        }
    }
    

    以上就是封装用于$app的几个异常处理方法了,接下来看一下Lumen对异常处理做的默认绑定,这里的单例绑定是接口绑定类的类型

    $app->singleton(
        IlluminateContractsDebugExceptionHandler::class,
        AppExceptionsHandler::class
    );
    

    app/Exceptions/Handler.php

    <?php
    
    namespace AppExceptions;
    
    use Exception;
    use IlluminateValidationValidationException;
    use IlluminateAuthAccessAuthorizationException;
    use IlluminateDatabaseEloquentModelNotFoundException;
    use LaravelLumenExceptionsHandler as ExceptionHandler;
    use SymfonyComponentHttpKernelExceptionHttpException;
    
    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.(在HTTP响应中呈现异常。)
         *
         * @param  IlluminateHttpRequest  $request
         * @param  Exception  $e
         * @return IlluminateHttpResponse
         */
        public function render($request, Exception $e)
        {
            return parent::render($request, $e);
        }
    }
    

    这个类继承了一个实现IlluminateContractsDebugExceptionHandler::class接口的异常处理基类LaravelLumenExceptionsHandler,这样,我们就可以很方便的做异常拦截和处理了!比如,

    public function render($request, Exception $e)
        {
            //数据验证异常拦截
            if ($e instanceof IlluminateValidationValidationException) {
                var_dump($e->validator->errors()->toArray());
            }
        
            return parent::render($request, $e);
        }
    

    这样我们就监听拦截到了Validation的ValidationException的异常,其实这部分往深扒的话,还有很多东西,如symfony下的debug和http-kernel两个模块的包,可以研究下

    Lumen技术交流群:310493206

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    mybatis中的延迟加载
    MyBatis的mapper
    MyBatis的resultMap
    mybatis入门
    mybatis中的#和$的区别(转)
    操作日志记录
    SpringMVC中的异常处理集锦
    vue.js的package.json相关问题解惑
    git的常用操作指令
    http协议参数详解
  • 原文地址:https://www.cnblogs.com/cxscode/p/7573381.html
Copyright © 2011-2022 走看看