/src/wrappers/glib/library/data_types/g_error.e

http://github.com/tybor/Liberty · Specman e · 347 lines · 81 code · 68 blank · 198 comment · 4 complexity · 525ea3537dfb3a47708154b456a58ad7 MD5 · raw file

  1. indexing
  2. description: "G_ERROR - information about an error that has occurred."
  3. copyright: "[
  4. Copyright (C) 2006 eiffel-libraries team, GTK+ team
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public License
  7. as published by the Free Software Foundation; either version 2.1 of
  8. the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. 02110-1301 USA
  17. ]"
  18. class G_ERROR
  19. -- The G_ERROR object contains information about an error that has
  20. -- occurred.
  21. -- GLib provides a standard method of reporting errors from a called
  22. -- function to the calling code. (This is the same problem solved by
  23. -- exceptions in other languages.) It's important to understand that this
  24. -- method is both a data type (the G_ERROR object) and a set of rules. If
  25. -- you use G_ERROR incorrectly, then your code will not properly
  26. -- interoperate with other code that use G_ERROR, and users of your API
  27. -- will probably get confused.
  28. -- First and foremost: G_ERROR should only be used to report recoverable
  29. -- runtime errors, never to report programming errors. If the programmer
  30. -- has screwed up, then you should use the facilities offered by
  31. -- GLIB_MESSAGE_LOGGING.
  32. -- Examples of recoverable runtime errors are "file not found" or "failed
  33. -- to parse input." Examples of programming errors are "NULL passed to
  34. -- strcmp()" or "attempted to free the same pointer twice." These two kinds
  35. -- of errors are fundamentally different: runtime errors should be handled
  36. -- or reported to the user, programming errors should be eliminated by
  37. -- fixing the bug in the program. This is why most functions in GLib and
  38. -- GTK+ do not use G_ERROR.
  39. -- Classes having features that can fail will insert SHARED_G_ERROR; each
  40. -- feature whose invocation can fail will change `error' and
  41. -- `is_successful'.
  42. -- Use 'matches' to see if the error
  43. -- matches a given domain and code
  44. -- (TODO) 'propagate' copies an error into an error location (so the calling
  45. -- function will receive it)
  46. -- 'clear' clears an error location by freeing the error and resetting
  47. -- the location to NULL.
  48. -- To display an error to the user,
  49. -- simply display 'message', perhaps along with
  50. -- additional context known only to the calling function
  51. -- (the file being opened, or whatever -- though in the
  52. -- g_file_get_contents() case, error->message already
  53. -- contains a filename).
  54. -- When implementing a function that can report errors,
  55. -- the basic tool is (TODO) 'set'. Typically, if a fatal
  56. -- error occurs you want to (TODO) 'set_error', then return
  57. -- immediately.
  58. -- TODO: Eiffellize. Things are somewhat more complicated if you yourself
  59. -- call another function that can report a GError. If the
  60. -- sub-function indicates fatal errors in some way other
  61. -- than reporting a GError, such as by returning TRUE on
  62. -- success, you can simply do the following:
  63. -- gboolean
  64. -- my_function_that_can_fail (GError **err)
  65. -- {
  66. -- g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
  67. -- if (!sub_function_that_can_fail (err))
  68. -- {
  69. -- /* assert that error was set by the sub-function */
  70. -- g_assert (err == NULL || *err != NULL);
  71. -- return FALSE;
  72. -- }
  73. -- /* otherwise continue, no error occurred */
  74. -- g_assert (err == NULL || *err == NULL);
  75. -- }
  76. -- If the sub-function does not indicate errors other than
  77. -- by reporting a GError, you need to create a temporary
  78. -- GError since the passed-in one may be
  79. -- NULL. g_propagate_error() is intended for use in this
  80. -- case.
  81. -- gboolean
  82. -- my_function_that_can_fail (GError **err)
  83. -- {
  84. -- GError *tmp_error;
  85. -- g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
  86. -- tmp_error = NULL;
  87. -- sub_function_that_can_fail (&tmp_error);
  88. -- if (tmp_error != NULL)
  89. -- {
  90. -- /* store tmp_error in err, if err != NULL,
  91. -- * otherwise call g_error_free() on tmp_error
  92. -- */
  93. -- g_propagate_error (err, tmp_error);
  94. -- return FALSE;
  95. -- }
  96. -- /* otherwise continue, no error occurred */
  97. -- }
  98. -- Error pileups are always a bug. For example, this code is incorrect:
  99. -- gboolean
  100. -- my_function_that_can_fail (GError **err)
  101. -- {
  102. -- GError *tmp_error;
  103. -- g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
  104. -- tmp_error = NULL;
  105. -- sub_function_that_can_fail (&tmp_error);
  106. -- other_function_that_can_fail (&tmp_error);
  107. -- if (tmp_error != NULL)
  108. -- {
  109. -- g_propagate_error (err, tmp_error);
  110. -- return FALSE;
  111. -- }
  112. -- }
  113. -- tmp_error should be checked immediately after
  114. -- sub_function_that_can_fail(), and either cleared or
  115. -- propagated upward. The rule is: after each error, you
  116. -- must either handle the error, or return it to the
  117. -- calling function. Note that passing NULL for the error
  118. -- location is the equivalent of handling an error by
  119. -- always doing nothing about it. So the following code is
  120. -- fine, assuming errors in sub_function_that_can_fail()
  121. -- are not fatal to my_function_that_can_fail():
  122. -- gboolean
  123. -- my_function_that_can_fail (GError **err)
  124. -- {
  125. -- GError *tmp_error;
  126. -- g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
  127. -- sub_function_that_can_fail (NULL); /* ignore errors */
  128. -- tmp_error = NULL;
  129. -- other_function_that_can_fail (&tmp_error);
  130. -- if (tmp_error != NULL)
  131. -- {
  132. -- g_propagate_error (err, tmp_error);
  133. -- return FALSE;
  134. -- }
  135. -- }
  136. -- Note that passing NULL for the error location ignores
  137. -- errors; it's equivalent to try {
  138. -- sub_function_that_can_fail(); } catch (...) {} in
  139. -- C++. It does not mean to leave errors unhandled; it
  140. -- means to handle them by doing nothing.
  141. -- Error domains and codes are conventionally named as follows:
  142. -- * The error domain is called
  143. -- <NAMESPACE>_<MODULE>_ERROR, for example G_EXEC_ERROR
  144. -- or G_THREAD_ERROR.
  145. -- * The error codes are in an enumeration called
  146. -- <Namespace><Module>Error; for example, GThreadError
  147. -- or GSpawnError.
  148. -- * Members of the error code enumeration are called
  149. -- <NAMESPACE>_<MODULE>_ERROR_<CODE>, for example
  150. -- G_SPAWN_ERROR_FORK or G_THREAD_ERROR_AGAIN. *
  151. -- If there's a "generic" or "unknown" error code for
  152. -- unrecoverable errors it doesn't make sense to
  153. -- distinguish with specific codes, it should be called
  154. -- <NAMESPACE>_<MODULE>_ERROR_FAILED, for example
  155. -- G_SPAWN_ERROR_FAILED or G_THREAD_ERROR_FAILED.
  156. -- Summary of rules for use of GError:
  157. -- * Do not report programming errors via GError.
  158. -- * The last argument of a function that returns an
  159. -- error should be a location where a GError can be
  160. -- placed (i.e. "GError** error"). If GError is used
  161. -- with varargs, the GError** should be the last
  162. -- argument before the "...".
  163. -- * The caller may pass NULL for the GError** if they
  164. -- are not interested in details of the exact error
  165. -- that occurred.
  166. -- * If NULL is passed for the GError** argument, then
  167. -- errors should not be returned to the caller, but
  168. -- your function should still abort and return if an
  169. -- error occurs. That is, control flow should not be
  170. -- affected by whether the caller wants to get a
  171. -- GError.
  172. -- * If a GError is reported, then your function by
  173. -- definition had a fatal failure and did not complete
  174. -- whatever it was supposed to do. If the failure was
  175. -- not fatal, then you handled it and you should not
  176. -- report it. If it was fatal, then you must report it
  177. -- and discontinue whatever you were doing immediately.
  178. -- * A GError* must be initialized to NULL before
  179. -- passing its address to a function that can report
  180. -- errors.
  181. -- * "Piling up" errors is always a bug. That is, if
  182. -- you assign a new GError to a GError* that is
  183. -- non-NULL, thus overwriting the previous error, it
  184. -- indicates that you should have aborted the operation
  185. -- instead of continuing. If you were able to continue,
  186. -- you should have cleared the previous error with
  187. -- g_clear_error(). g_set_error() will complain if you
  188. -- pile up errors. *
  189. -- By convention, if you return a boolean value
  190. -- indicating success then TRUE means success and FALSE
  191. -- means failure. If FALSE is returned, the error must
  192. -- be set to a non-NULL value.
  193. -- * A NULL return value is also frequently used to
  194. -- mean that an error occurred. You should make clear
  195. -- in your documentation whether NULL is a valid return
  196. -- value in non-error cases; if NULL is a valid value,
  197. -- then users must check whether an error was returned
  198. -- to see if the function succeeded.
  199. -- * When implementing a function that can report
  200. -- errors, you may want to add a check at the top of
  201. -- your function that the error return location is
  202. -- either NULL or contains a NULL error
  203. -- (e.g. g_return_if_fail (error == NULL || *error ==
  204. -- NULL);).
  205. inherit
  206. C_STRUCT
  207. redefine free_handle
  208. end
  209. insert
  210. GERROR_EXTERNALS
  211. GERROR_STRUCT
  212. creation
  213. make, empty, from_external_pointer
  214. feature {} -- Creation
  215. make (a_domain: G_QUARK; a_code: INTEGER; a_message: STRING) is
  216. -- Creates a new G_ERROR
  217. do
  218. from_external_pointer (g_error_new_literal (a_domain.quark, a_code, a_message.to_external))
  219. ensure not_null: handle.is_not_null
  220. end
  221. empty is
  222. do
  223. -- This feature is empty by design. No initialization is
  224. -- needed because the feature that will return an error will
  225. -- allocate a GError C structure, changing the value of
  226. -- handle
  227. end
  228. feature -- Access
  229. is_set: BOOLEAN is
  230. -- Has Current been set? Usually it is set by a call to a C library
  231. do
  232. Result := handle.is_not_null
  233. end
  234. domain: G_QUARK is
  235. -- The module whewre the error-reporting feature is located in.
  236. require is_set
  237. do
  238. Result.set_quark (gerror_struct_get_domain (handle))
  239. end
  240. code: INTEGER is
  241. -- The specific error that occurred encoded as a programmer-defined
  242. -- constant.
  243. require is_set
  244. do
  245. Result := gerror_struct_get_code (handle)
  246. end
  247. message: STRING is
  248. -- a user-readable error message with as many details as possible.
  249. require is_set
  250. local
  251. ptr: POINTER
  252. do
  253. ptr := gerror_struct_get_message (handle)
  254. if ptr.is_not_null then
  255. create Result.from_external_copy (ptr)
  256. end
  257. end
  258. feature -- Comparison
  259. matches (a_domain: G_QUARK; a_code: INTEGER): BOOLEAN is
  260. -- Does Current G_ERROR matches 'a_domain' and 'a_code'?
  261. require is_set
  262. do
  263. Result := g_error_matches (handle, a_domain.quark, a_code).to_boolean
  264. end
  265. feature -- Disposing
  266. dispose is
  267. -- Frees a G_ERROR and associated resources.
  268. do
  269. if is_set then
  270. free_handle
  271. end
  272. end
  273. free_handle is
  274. require is_set
  275. do
  276. g_error_free (handle)
  277. handle := default_pointer
  278. end
  279. end