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