error.h.xml 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <chapter xml:id="error.h">
  2. <title><tt>__vic/error.h</tt></title>
  3. <p>Error handling tools.</p>
  4. <chapter xml:id="exception">
  5. <title><tt>exception</tt></title>
  6. <code-block lang="C++">
  7. class exception : public std::exception
  8. {
  9. public:
  10. exception();
  11. explicit exception(const char *message);
  12. const char *what() const noexcept;
  13. protected:
  14. void set_message(const char *message);
  15. };
  16. </code-block>
  17. <p>Small extension of <tt>std::exception</tt> - the object carries message
  18. specified in the constructor, <tt>what()</tt> returns this message. Can be used
  19. either as a base or a concrete exception class. Does not use/depend on
  20. <tt>std::string</tt> as opposed to <tt>std::logic_error</tt> and
  21. <tt>std::runtime_error</tt>. You also don't have to decide which one of them
  22. you should use in the particular case.</p>
  23. <section><title>Class members</title>
  24. <synopsis>
  25. <prototype>exception()</prototype>
  26. <p>Creates the object with an empty message.</p>
  27. </synopsis>
  28. <synopsis>
  29. <prototype>explicit exception(const char *message)</prototype>
  30. <p>Creates the object with the specified message.</p>
  31. </synopsis>
  32. <synopsis>
  33. <prototype>const char *what() const noexcept</prototype>
  34. <p>Returns the message specified before.</p>
  35. </synopsis>
  36. <synopsis>
  37. <prototype>void set_message(const char *message)</prototype>
  38. <p>Sets a new message.</p>
  39. </synopsis>
  40. </section>
  41. <section><title>Example</title>
  42. <code-block lang="C++">
  43. struct custom_exception : public __vic::exception
  44. {
  45. explicit custom_exception(const char *msg) : __vic::exception(msg) {}
  46. };
  47. throw custom_exception("Error condition description");
  48. </code-block>
  49. </section>
  50. </chapter>
  51. <chapter xml:id="libc_error">
  52. <title><tt>libc_error</tt></title>
  53. <code-block lang="C++">
  54. class libc_error : public std::exception
  55. {
  56. public:
  57. explicit libc_error(int err_no = errno);
  58. explicit libc_error(const char *prompt, int err_no = errno);
  59. const char *what() const noexcept;
  60. int code() const;
  61. int get_errno() const;
  62. };
  63. </code-block>
  64. <p>This class is an easy and straightforward replacement of the standard error
  65. handling machinery used in the C-world - <tt>errno</tt>, with exceptions. The
  66. class is also suitable for usage in the multithread environment instead of
  67. not always reentrant call <tt>std::strerror()</tt>.</p>
  68. <p>Below you can see typical C code:</p>
  69. <code-block lang="C">
  70. // C:
  71. int fd;
  72. if((fd = open("qqqq", O_RDONLY)) == -1)
  73. {
  74. perror("open");
  75. if(errno == ENOENT) exit(1);
  76. }
  77. </code-block>
  78. <p>If the file is not found, the message like this</p>
  79. <tty>
  80. open: No such file or directory
  81. </tty>
  82. <p>is printed to <tt>stderr</tt> and the program exits with the status
  83. <tt>1</tt>.</p>
  84. <p>What issues are inherent in this code? Firstly, not every program has
  85. <tt>stderr</tt>, so a library function is not allowed to print error messages
  86. there. Secondly, the value of the global variable <tt>errno</tt> can be
  87. rewritten by any subsequent call unless the value is saved explicitly right
  88. after the call. Thirdly, the decision about termination of the process can only
  89. be made by the application. An ordinary library function is not allowed to do
  90. this. Fourthly, in general case C++ program cannot call <tt>std::exit()</tt>,
  91. because destructors of the live objects allocated on the stack won't be
  92. called, and program's logic can be corrupted.</p>
  93. <p>The example adapted for C++ using our class:</p>
  94. <code-block lang="C++"><![CDATA[
  95. // C++:
  96. try
  97. {
  98. int fd = open("qqqq", O_RDONLY);
  99. if(fd == -1) throw __vic::libc_error("open");
  100. // or just
  101. // if(fd == -1) throw __vic::libc_error();
  102. }
  103. catch(const __vic::libc_error &ex)
  104. {
  105. std::cerr << ex.what() << '\n';
  106. if(ex.code() == ENOENT) return 1;
  107. }
  108. ]]></code-block>
  109. <p>As it can be seen, the function handles erroneous situation correctly and
  110. reports it to the caller. Afterwards the caller can handle the error
  111. appropriately. In the elementary case it acts as the former C-program: prints
  112. the message to the standard error output stream and terminates. Moreover,
  113. error code is now saved in the exception and cannot be rewritten by accident.
  114. </p>
  115. <note>Usually exceptions of this class shouldn't be thrown explicitly! Use
  116. <xref to="throw_errno"/> instead.</note>
  117. <section><title>Class members</title>
  118. <synopsis>
  119. <prototype>explicit libc_error(int err_no = errno)</prototype>
  120. <p><tt>err_no</tt> - error code.</p>
  121. <postcondition><tt>code() == err_no</tt></postcondition>
  122. </synopsis>
  123. <synopsis>
  124. <prototype>explicit libc_error(const char *prompt, int err_no = errno)</prototype>
  125. <p><tt>prompt</tt> - a title of the error message. The parameter has the same
  126. meaning as the parameter of <tt>std::perror()</tt>.</p>
  127. </synopsis>
  128. <synopsis>
  129. <prototype>const char *what() const noexcept</prototype>
  130. <p>Returns error description in the <tt>std::perror()</tt> format.</p>
  131. </synopsis>
  132. <synopsis>
  133. <prototype>int code() const</prototype>
  134. <prototype>int get_errno() const</prototype>
  135. <p>Returns stored error code.</p>
  136. </synopsis>
  137. </section>
  138. </chapter>
  139. </chapter>