• nginx源码分析 -异常处理


    1.源码错误处理

    Nginx使用传统的错误码处理错误(注意与HTTP的响应状态码200、404等是不同的),但在C++里使用异常(exception)的方式会更好。因为异常机制可以分离代码逻辑里的正 常部分与异常部分,使代码的结构更加清晰
    源码:
    1. #define NGX_OK 0;
    2. #define NGX_ERROR -1;
    3. #define NGX AGAIN - 2 // 未准备好,需要重试
    4. #define NGX BUSY - 3 //后端服务正忙
    5. #define NGX DONE -4 //执行成功 ,但还需要有后续操作
    6. #define NGX DECLINED -5 //执行成功 ,但未做处
    7. #define NGX ABORT -6 //发生了严重 的错误

    2.c++改造

    2.1

    1. public:
    2. NgxException(ngx_int_t x, string_ref_type msg):
    3. m_code(x), m_msg(msg)
    4. {}
    5. NgxException(ngx_int_t x = NGX_ERROR):
    6. NgxException(x, "")
    7. {}
    8. NgxException(string_ref_type msg):
    9. NgxException(NGX_ERROR, msg)
    10. {}
    11. virtual ~NgxException() noexcept
    12. {}
    13. ngx_int_t code() const
    14. {
    15. return m_code;
    16. }
    17. virtual const char* what() const noexcept override
    18. {
    19. return m_msg.c_str();
    20. }
    21. private:
    22. ngx_int_t code=NGX_ERROR;
    23. std::string m_msg;

    1.设置成员 code(错误码) 以及错误信息

    2.设置访问函数 来访问code 

    3.解析override

    override保留字表示当前函数重写了基类的虚函数

    在函数比较多的情况下可以提示读者某个函数重写了基类虚函数,表示这个虚函数是从基类继承,不是派生类自己定义的;强制编译器检查某个函数是否重写基类虚函数,如果没有则报错。在类的成员函数参数列表后面添加该关键字既可。

    表示这个函数是继承what();

    4.初始化

    1.已经有default构造

    2.也设置赋值构造

    3.委托构造

      在c++11中有一个新特性,就是委托构造函数。委托构造函数可以使用当前类其他构造函数来帮助当前构造函数初始化。换而言之,就是可以将当前构造函数的部分(或者全部)职责交给本类的另一个构造函数

        我们先看看委托构造函数与普通构造函数的相同点与不同点。

    相同点: 两者都有一个成员初始值列表与一个函数体 不同点:

    委托构造函数的成员初始值列表只有一个唯一的参数,就是构造函数(当然不能是当前的构造函数)   

    2.2

    1. static void raise(ngx_int_t rc = NGX_ERROR, string_ref_type msg = "")
    2. {
    3. throw NgxException(rc, msg);
    4. }
    5. static void require(bool cond, ngx_int_t e = NGX_ERROR, string_ref_type msg = "")
    6. {
    7. if(!cond)
    8. {
    9. raise(e, msg);
    10. }
    11. }
    12. static void require(ngx_int_t rc, ngx_int_t x = NGX_OK, string_ref_type msg = "")
    13. {
    14. require(rc == x, rc, msg);
    15. }
    16. template<typename T>
    17. static void require(T* p, ngx_int_t e = NGX_ERROR, string_ref_type msg = "")
    18. {
    19. require(p != nullptr, e, msg);
    20. }
    21. static void fail(bool cond, ngx_int_t e = NGX_ERROR, string_ref_type msg = "")
    22. {
    23. if(cond)
    24. {
    25. raise(e, msg);
    26. }
    27. }

    1. 异常的通常使用方式是直接用throw抛出,但这里我们把它封装为一个raise ( )函数,表现形式更好

    2.检查错误码和空指针是 Nginx开发中经常要做的工作。反复出现的if语句很麻烦,由于异常处理流程与正常流程是分离的,所以可以轻松写出封装函数require( ) :

    1. static void require(bool cond, ngx_int_t e = NGX_ERROR, string_ref_type msg = "")
    2. {
    3. if(!cond)
    4. {
    5. raise(e, msg);
    6. }
    7. }
    8. static void require(ngx_int_t rc, ngx_int_t x = NGX_OK, string_ref_type msg = "")
    9. {
    10. require(rc == x, rc, msg);
    11. }
    12. template<typename T>
    13. static void require(T* p, ngx_int_t e = NGX_ERROR, string_ref_type msg = "")
    14. {
    15. require(p != nullptr, e, msg);
    16. }

    3.有的时候当判断条件成立时的逻辑更容易书写,所以require()的“反函数”fail ()也很有用:

    1. static void fail(bool cond, ngx_int_t e = NGX_ERROR, string_ref_type msg = "")
    2. {
    3. if(cond)
    4. {
    5. raise(e, msg);
    6. }
    7. }

  • 相关阅读:
    指定vscode黏贴图片路径(VSCode 1.79 更新)
    卷积神经网络 语义分析,卷积神经网络文字识别
    HTTP的前世今生
    转载-什么是微码Microcode
    Linux下进程地址空间初步理解
    深入了解iOS内存(WWDC 2018)笔记-内存诊断
    AppData文件夹下Local,Locallow和Roaming
    LeetCode 706: Design HashMap (Hash设计好题)
    SSM整合流程
    day46:C++ day6 继承过程中的特殊成员函数、多重继承、虚继承、多态、泛型编程模板
  • 原文地址:https://blog.csdn.net/qq_62309585/article/details/127937922