美文网首页
Swoole + Yaf 解决统一处理业务层未捕获异常Bug

Swoole + Yaf 解决统一处理业务层未捕获异常Bug

作者: codezm | 来源:发表于2019-08-22 17:44 被阅读0次
背景

项目架构采用 Swoole\Http\Server + Yaf 实现,业务层 Yaf 若有未捕获异常配置如下:

application.dispatcher.throwException = 1
; 开启此项,如果有未捕获的异常,Yaf将会把它定向到Error controller, Error Action。
application.dispatcher.catchException = 1

业务层所有未捕获异常可在 ErrorController->ErrorAction 中处理。

解决方案是更改 Yaf 配置项 application.dispatcher.catchException = 0worker 中对 Yaf 层做 try{...}catch(...) 处理。

深度解析

Yaf 源码文件 yaf_dispatcher.c 中的 yaf_dispatcher_exception_handler 方法对异常做了处理: YAF_G(in_exception) = 1;,在 PHP_RSHUTDOWN_FUNCTION 模块做的清除工作。导致 Swoole 的每个 worker 仅在进程首次可以由 ErrorController->ErrorAction 捕获异常,其他情况将导致 worker 进程异常退出。

源码解决方案:

  • yaf_dispatcher_exception_handler 方法尾部追加 YAF_G(in_exception) = 0;
  • 自定义清除函数, ErrorController 中处理异常后调用 $this->clear(); 重置。
$ vim yaf_controller.c

PHP_METHOD(yaf_controller, clear) {
    YAF_G(in_exception) = 0;

    RETURN_TRUE;
}

/** {{{ yaf_controller_methods
*/
zend_function_entry yaf_controller_methods[] = {
    PHP_ME(yaf_controller, render,      yaf_controller_render_arginfo,  ZEND_ACC_PROTECTED)
    PHP_ME(yaf_controller, display,     yaf_controller_display_arginfo, ZEND_ACC_PROTECTED)
    PHP_ME(yaf_controller, getRequest,  yaf_controller_void_arginfo,    ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, getResponse, yaf_controller_void_arginfo,    ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, getModuleName,yaf_controller_void_arginfo,   ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, getView,     yaf_controller_void_arginfo,    ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, initView,    yaf_controller_initview_arginfo,ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, setViewpath, yaf_controller_setvdir_arginfo, ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, getViewpath, yaf_controller_void_arginfo,    ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, forward,     yaf_controller_forward_arginfo, ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, redirect,    yaf_controller_redirect_arginfo,ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, getInvokeArgs,yaf_controller_void_arginfo,   ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, getInvokeArg, yaf_controller_getiarg_arginfo,ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, clear,       NULL,                           ZEND_ACC_PUBLIC)
    PHP_ME(yaf_controller, __construct, NULL,                           ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
    PHP_ME(yaf_controller, __clone,     NULL,                           ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
    {NULL, NULL, NULL}
};

/* }}} */

相关文章

  • Swoole + Yaf 解决统一处理业务层未捕获异常Bug

    背景 项目架构采用 Swoole\Http\Server + Yaf 实现,业务层 Yaf 若有未捕获异常配置如下...

  • springboot之统一异常处理

    spring统一异常处理 使用spring的统一异常处理,我们就不再需要在业务代码中就行显式的捕获异常处理,在da...

  • Dubbo 自定义异常,你是怎么处理的?

    前言 记录Dubbo对于自定义异常的处理方式. 实现目标 服务层异常,直接向上层抛出,web层统一捕获处理 如果是...

  • 极客时间第16天

    今天学习的是异常处理的正确方式. 从中我学到了什么: 不要用统一的方式去捕获异常,因为异常分为系统异常和业务异常,...

  • 6未捕获的异常

    如果一个异常未被捕获,则由名为未捕获异常处理程序的函数截取。未捕获的异常处理程序总是导致程序退出,但可能会在这之前...

  • nestjs异常过滤器

    内置的异常层负责处理整个应用程序中的所有抛出的异常。当捕获异常的时候根据异常错误码进行业务处理,最终客户会收到友好...

  • SpringBoot全局异常处理

    一般在企业里面对这些异常一般都会统一捕获,由一个专门的异常处理类来统一处理。 2.11.1.异常捕获 packag...

  • thinkphp5.0 全局异常捕获处理

    一、异常捕获和处理 模拟 model层出现了异常,在controller层捕获异常,并给前端返回json格式异常信...

  • 工作总结-002

    异常捕获service捕获业务异常,自定义BaseException;interface捕获业务异常,以及其他异常...

  • springboot 异常捕获和处理

    springboot 异常捕获和处理 异常捕获处理

网友评论

      本文标题:Swoole + Yaf 解决统一处理业务层未捕获异常Bug

      本文链接:https://www.haomeiwen.com/subject/cyqosctx.html